So I had this script that makes our dev and test environment and blahblah. In other words I needed to verify that what I had was good before starting the process and that checked if everything succeeded as it was supposed to after the script runs. Seems like what I needed were a bunch of tests. First to check no one tampered with the bits I needed to make this work and in the end see if the things I did worked. I repeated myself didn’t I? Good.
So first of all I wrote some simple tests and found this piece of code on the StackOverflow site
Namespace TestFramework
Public Class AssertAll
Public Shared Function Succeed(ParamArray assertions As Action()) As String
Dim errors = New List(Of String)()
Console.WriteLine("Running {0} tests.", assertions.Count)
For Each assertion In assertions
Try
assertion()
Catch ex As Exception
errors.Add(String.Format("Test {0} failed with message {1}", assertion.Method.Name, ex.Message))
End Try
Next
If (errors.Any()) Then
Console.WriteLine("{0} tests failed, {1} tests passed.", errors.Count, assertions.Count - errors.Count)
For Each errorDescription In errors
LogTo.Warn(errorDescription)
Next
Throw New Exception(String.Format("{0} tests failed, {1} tests passed.", errors.Count, assertions.Count - errors.Count))
End If
Console.WriteLine("All {0} tests passed.", assertions.Count)
Return String.Format("All {0} tests passed.", assertions.Count)
End Function
End Class
End Namespace
This ofcourse wants you to pass it some actions which are our tests.
Public Function Execute() As String
Console.WriteLine("Running tests for {0}", Me.GetType.Name)
Dim methods = Me.GetType().GetMethods().Where(Function(m) m.GetCustomAttributes(GetType(TestAttribute), False).Length > 0)
Dim tests = (From t In methods Select [Delegate].CreateDelegate(GetType(Action), Me, t)).Cast(Of Action)().ToList()
Return AssertAll.Succeed(tests.ToArray)
End Function
Or something like that.
This was in a baseclass from which testclasses inherit (so you can pass some much needed parameters to them and then you just call execute and BAM! tests run.
This however only works for “simple” tests. As soon as you start to use testcase you are in trouble and a world of much code. Much code means much work and I don’t like to work. But I don’t have too. Because I can run the tests another way, with nunit.engine.
Just nuget the NUnit.Engine package and make sure everyone of those files is in your outputfolder
(I don’t care how you do this just make it happen, no need to kill kittens for this, but if you must).
I guess you don’t need the config or addins file.
After that you can run tests with this.
Imports System.Reflection
Imports System.Xml
Imports NUnit.Engine
Namespace TestFramework
Public Class RunTests
Public Shared Function Run(ByVal category As String) As String
Dim returnvalue = ""
Dim path = Assembly.GetExecutingAssembly().Location
Dim package = New TestPackage(path)
package.AddSetting("WorkDirectory", Environment.CurrentDirectory)
Dim engine = TestEngineActivator.CreateInstance()
Dim filterService = engine.Services.GetService(Of ITestFilterService)()
Dim builder = filterService.GetTestFilterBuilder()
builder.SelectWhere("cat==" & category)
Dim emptyFilter = builder.GetFilter
Using runner = engine.GetRunner(package)
Dim explore = runner.CountTestCases(emptyFilter)
Console.WriteLine("Running {0} tests.", explore)
Dim result = runner.Run(New Listener, emptyFilter)
If result.Attributes.GetNamedItem("result").InnerText = "Passed" Then
returnvalue = String.Format("All {0} tests passed.", result.Attributes.GetNamedItem("total").InnerText)
Console.WriteLine("All {0} tests passed.", result.Attributes.GetNamedItem("total").InnerText)
Else
Console.WriteLine("Some of the {0} tests failed. Passed: {1} , failed {2}", result.Attributes.GetNamedItem("total").InnerText, result.Attributes.GetNamedItem("passed").InnerText, result.Attributes.GetNamedItem("failed").InnerText)
For Each r As XmlNode In result.SelectNodes("//test-case[contains(@result, 'Failed')]")
If r.SelectSingleNode("//failure").ChildNodes.Count = 1 Then
Console.WriteLine("Test {0} failed with error {1}.", r.Attributes.GetNamedItem("name").InnerText, r.SelectSingleNode("//failure").ChildNodes(0).InnerText)
Else
Console.WriteLine("Test {0} failed with error {1} with stacktrace {2}.", r.Attributes.GetNamedItem("name").InnerText, r.SelectSingleNode("//failure").ChildNodes(0).InnerText, r.SelectSingleNode("//failure").ChildNodes(1).InnerText)
End If
Next
Throw New Exception(String.Format("Some of the {0} tests failed. Passed: {1} , failed {2}", result.Attributes.GetNamedItem("total").InnerText, result.Attributes.GetNamedItem("passed").InnerText, result.Attributes.GetNamedItem("failed").InnerText))
End If
End Using
Return returnvalue
End Function
End Class
Public Class Listener
Implements ITestEventListener
Public Sub OnTestEvent(report As String) Implements ITestEventListener.OnTestEvent
Console.WriteLine(report)
End Sub
End Class
End Namespace
As you can see I have a filter on category for the above.
This might be of use for you
- NUnit.Engine.Api
- The tests to figure out what goes in the SelectWhere method.
- The testresults xml format
- One of the errors you might get and a solution
And that’s it. Any questions?