Blog

History of UquoniTest

Some people asked me about the history of UquoniTest, especially why the present version is 2.0 while they never heard of the version 1.0.

Well, there was a version 1.0 in september 2006, but after a while I felt it was not yet good enough, so I continued development. Lorré Engineering bought licenses, who until then used CxxUnit and were happy to switch. We didn't market it well because we preferred to build a better version.

 


Posted by: markvp on the 16/04/2010 12:29 | Categories: General,

Book review of The Art of Unit Testing

I just came across this book review of The Art of Unit Testing on Slashdot. The review is very positive.

Also interesting is the discussion that follows it at Slashdot. I always enjoy discussions at Slashdot, because many participants in the discussions have a lot of experience, and the system with the moderator points filters out less interesting parts of the discussion.

The book xUnit Test Patterns: Refactoring Test Code by Gerard Meszaros is mentioned in some posts as an alternative, which is indeed a good book.

 I noticed some posts of people that claim that unit testing doesn't work for them. However, in my experience this is usually because people are not very familiar with using interfaces. Making a class use an interface to some fuctionality instead of having a pointer to the real thing makes it easy to use mocks, and hence improve testability. I've actually never seen software code where unit tests couldn't be used. It may vary among applications, e.g. applications that need to use the API of an OS, where testing that the correct parameters are given to the API is hard, but in the end there is always a substantial amount of code that has some logic to it that can be tested with unit tests.


Posted by: markvp on the 12/02/2010 11:05 | Categories: General,

Testing assertions

By making UquoniTest compatible with CppUnit, I encountered their assertions that test assertions. Apparently they provide this feature so that users that create custom assertions, can test them with unit tests.

I hadn't considered this yet for UquoniTest, but with UquoniTest there is less need to do this, because the assertions can use Rich Booleans. Most custom assertions can be handled with custom Rich Booleans that are used in the standard assertions. And the easiest way to create a Rich Boolean is by creating a class that implements some requirements. This class can be tested thoroughly in unit tests, and turning it in a Rich Boolean just requires a wrapper.

To be compatible with CppUnit I implemented the feature, so there is now a UquoniTest version of this - actually implemented as a Rich Boolean! I think it can be useful for those (rare) cases where a developer wants a custom assertion for which a custom Rich Boolean won't do; or even for those who write a custom Rich Boolean, but want to check if nothing went wrong with the wrapper.


Posted by: markvp on the 29/01/2010 11:25 | Categories: General,

How is UquoniTest tested?

People keep asking me how UquoniTest itself is tested. I'm sure it's an intriguing question to many people. So I decided to explain this on my blog.

UquoniTest is tested in three different ways, that complement each other.

First there are of course unit tests to test functionality of the code. And this is tested with UquoniTest itself. There are two tricky things about this. First I have to make sure that an error in UquoniTest doesn't cover up this error by not reporting the error. Until now this hasn't happened yet, because it is quite unlikely. It can be a bit annoying at times if a serious bug is introduced, like when I recently rewrote the TestWrapper functionality. Second there is some global state in UquoniTest. I'm working to remove this but I'm not yet there. To prevent this from causing problems, the tested code is put in a different namespace. You may have noticed 'namespace UQUONITEST' in many headerfiles. Usually UQUONITEST is defined as UquoniTest, but when the code is tested it is defined as TestUquoniTest, so that changing anything in the global state doesn't interfere with the framework.

Second there are integration tests where I test whether test code behaves as expected, e.g. whether any possible failure is reported, or whether the code in an ignored test is not run. To do this I have macros like EXPECT_FAILURE(condition, analysis, delta) or EXPECT_IGNORED_TEST(delta), where delta says how many lines down it is expected to be. This is the most extensive part of the tests, and is divided in four projects: one for assertions, one for abstract tests, one for mocks and one for the other functionality.

Third there are tests for checking whether command line options are processed well. To do this I created a test listener, that reads a file that specifies which tests should be run, and what output should be produced. E.g. a file IncludeGroup1.txt contains

Group1::Test1
Group1::Test2
Group1::ParamTest(1)
Group1::ParamTest(2)

A script file contains commands like "UquoniTest_TestCmdLine -tests IncludeGroup1.txt -ig Group1", and the test listener checks whether all the mentioned tests are run, and no other tests. The script file contains over 80 commands like this.

These tests test every possible feature of UquoniTest. I hope this explanation satisfies those who are curious about how UquoniTest is tested.


Posted by: markvp on the 18/01/2010 12:18 | Categories: General,

Using tests from other unit test packages

I recently decided to add a nice feature to UquoniTest: allow users to use tests that were written in other C++ unit testing packages. For developers who already implemented a lot of tests in another unit testing package, but want to switch to UquoniTest, this is obviously important. I intend to eventually do it for UnitTest++, CPPUnit, Boost Test, CxxTest and GoogleTest.

Since UquoniTest has about all the features that these other unit testing packages have, and more, I thought it would be quite easy. Just define macros to something equivalent to those in UquoniTest, and add some workarounds for things that are done differently.

Well, it turns out that those workarounds are more work than I thought. The most important is the manual registering in CPPUnit (optional in Boost Test, probably for backward compatibility), but also smaller things like specifying a maximum test time, which in UnitTest++ is done inside a test instead of as a tag in front of the test, and the group fixtures in Boost Test. All these can be done in UquoniTest as well, but in a different way, which has me scratching my head looking for a way to use them in an elegant way in UquoniTest.

Well, it's a lot of fun to do actually, although I wish it took less time.


Posted by: markvp on the 30/12/2009 12:55 | Categories: General,