reflection based unit testing

Monkey Archive Forums/Monkey Projects/reflection based unit testing

wiebow(Posted 2012) [#1]
ITS WORKING.

Finally, after a few false starts, reflection bugs and getting to know the new monkey reflection principles, it is now working. Thanks for Brucey for the great MaxUnit which I used as an example to get things working...
you can get the source from my google code page, address is in my signature. There is also a zip file in the download section. I hope it will be of use to you.

I like to develop with unit tests as it saves me a lot of time and bug hunting. It is not for everyone, BUT, as Monkey has no debugger yet this is a great way to develop and test large or small projects.

Setting up unit tests is childs play now:
Strict

#REFLECTION_FILTER+="*_test"

Import wdw.unittest
Import simple_test

Function Main:Int()
        Local t:TestSuite = New TestSuite
        t.Run()
        Return 0
End


Class MyClassTest Extends TestBase
	
	Field m:MyClass

	
	Method dothisBefore:Void()
		'we do this before each unit test
		m = New MyClass
	End
	
	Method dothisAfter:Void()
		'we do this after each unit test
		m = Null
	End
	
	
	Method constructorTest:Void()
		Self.assertNotNull(m)
	End	

'this test will fail, of course.		
	Method constructorFailingTest:Void()
		Self.assertNull(m)
	End
	
End


Class MyClass
	
	Private	
	Field simplefield:Int
	Public	
	
	Method Simplefield:Int(i:Int) Property
		simplefield = i
		Return 0
	End
	
	Method Simplefield:Int() Property
		Return simplefield
	End
End



slenkar(Posted 2012) [#2]
I dont understand..yet

A unit test is when you are trying to perfect a function or routine and you make a small sample program to get it right, right?

so what does the reflection do?


wiebow(Posted 2012) [#3]
Yes, a unit test tests a small bit of code. You write small tests, and all those tests together prove that your code works before you implement it in a larger project. One of the great things of test driven development is that you only write the code you really need (write tests for)

Basically, you are writing a test program to test your project code.

Reflection in this case inspects the test class (In the example, this is MyTestclass) at runtime, making it really easy to add tests. The example performs two tests, one passes and one fails. Maybe I must expand the example a bit, but brucey wrote a really nice tutorial here: http://code.google.com/p/maxmods/wiki/MaxUnitModule

I also have a wiki page here: http://code.google.com/p/mutated-monkey/wiki/unittest


TheRedFox(Posted 2012) [#4]
It finds and runs the tests in the tests without having to specify them all with code.


Beaker(Posted 2012) [#5]
Looks very neat. Definitely going to get some use here.


wiebow(Posted 2012) [#6]
Always willing to help you out, Beaker :) Yell when something bugs you and needs change.


wiebow(Posted 2012) [#7]
I updated the module for 1.60... Using exceptions and better output.

http://code.google.com/p/mutated-monkey/downloads/list?saved=1&ts=1340459442

or use the link in my sig.


wiebow(Posted 2012) [#8]
I updated the module to version 1.2 for Monkey v66. Reflection filter changes, awesome Mark.

I also updated the wiki page: http://code.google.com/p/mutated-monkey/wiki/unittest


NoOdle(Posted 2012) [#9]
please excuse my ignorance, but what would unit testing allow me to see? What are the benefits of using it in a project? Please can you provide an example of where it has helped you? I have a feeling this module is really useful and I need to know more! Thank you


wiebow(Posted 2012) [#10]
Hi Noodle. No problem.

The big advantage of unit testing is that you test your code in small chunks and in a small test program, beforehand, instead of using the old 'add code to game and compile the complete game to see if it works' approach.

For instance, look at the vector2d module tests I've made at:
http://code.google.com/p/mutated-monkey/source/browse/wdw/tools/test/vector2d_test.monkey

Now, I have not used this vector2d class in a game yet, but I KNOW it works, because I tested each method that needed testing, beforehand, in this test. Therefore, I know for sure that problems I encounter during the making of a game come from the implementation and not from the actual modules I use.

You can go all the way: write tests before you write code. This is called test-driven-development. It really works: You need new functionality, you write a test, see it fail, add code to make test pass, repeat. You'll never write redundant code again.

This is of course overkill for small projects, but this way I can create quality code real quick. Unit testing has allowed me to port the Java Framework 'Artemis' to blitzmax, almost bug free on the first go.


Rushino(Posted 2012) [#11]
Wiebow that pretty awesome! Probably one of the best module around there ! :) What you have done so far regarding asserts ? Are they many implemented yet ?


wiebow(Posted 2012) [#12]
Rushino, thanks!
I've been using this module for some time now and not had the need for more asserts than it currently has. The asserts are in this source file: http://code.google.com/p/mutated-monkey/source/browse/wdw/unittest/assert.monkey

As you can see, it's fairly complete. But I am taking suggestions :)


nigelibrown(Posted 2014) [#13]
./main.cpp:8093:15: error: variable or field 'gc_mark' declared void
../main.cpp:8093:21: error: missing template arguments before '*' token
../main.cpp:8093:22: error: 'p' was not declared in this scope
../main.cpp:8094:18: error: 'String dbg_type' redeclared as different kind of symbol
../main.cpp:8092:8: error: previous declaration of 'String dbg_type(c_R282**)'
../main.cpp:8094:24: error: missing template arguments before '*' token
../main.cpp:8094:26: error: 'p' was not declared in this scope
../main.cpp:8095:19: error: 'String dbg_value' redeclared as different kind of symbol
../main.cpp:1402:26: error: previous declaration of 'template<class T> String dbg_value(Array<T>*)'
../main.cpp:8095:25: error: missing template arguments before '*' token
../main.cpp:8095:27: error: 'p' was not declared in this scope
mingw32-make: *** [../main.o] Error 1

Any other modules that allow this in later Monkey releases?