Jump to content
  • Advertisement
Sign in to follow this  
Angelic Ice

How to use Unit-Tests

This topic is 728 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello forum!

 

I'm trying to get my head around unit testing.

I chose this library, Catch: https://github.com/philsquared/Catch

 

I have a rather large project and I do not really understand on how to add tests to it.

 

Maybe I'm still misunderstand unit testing.

 

Should I store unit tests in extra files? When yes, why?

I thought I would do those once I obtain parameter values or execute a void and see if what I expected happened - checking whether code behaves as expected.

 

But it seems more of writing tests for a specific testing aspect in a different file for all possible cases:

TEST_CASE( "Factorials are computed", "[factorial]" ) {
    REQUIRE( Factorial(1) == 1 );
    REQUIRE( Factorial(2) == 2 );
    REQUIRE( Factorial(3) == 6 );
    REQUIRE( Factorial(10) == 3628800 );
}

Code excerpt from: https://github.com/philsquared/Catch/blob/master/docs/tutorial.md

 

Therefore, testing mathematical calculations is probably not a thing that should be tested for every possible outcome.

 

But testing whether my buffer-instance owns one instance after pushing one instance, would be a unit test?

Though, would I invoke them into the actual code or are they just residing in another file? And if yes, how do they actually interact then?

 

An example:

My "real" code that tries to solve a problem, runs a for-loop as often as needed (not known at compile time) and push one object per iteration onto the buffer class instance.

Now, it will be run seven times. How would a unit test look?

When it is in another file, it would be run first and only check whether adding one unit will add one unit to the buffer (assuming it owned 0 from its construction point). Another test would be checking on if the size of buffer is increasing after it reached it maximum capacity?

So that would be 2 unit tests.

 

I always thought I would just simply add REQUIRE( buffer_object.get_size() == i ); inside the for-loop.

 

I think, it would help a lot if you could show me a simple example on how to invoke unit testing into a tiny code example using a class and whatnot.

The greatest issue of understanding seems to be, where to place the unit tests? How to invoke them into code?

Share this post


Link to post
Share on other sites
Advertisement

Unit tests first and foremost are a way to ensure permanence.  They are there to ensure that when you provide an input, you get the expected output.  Normally it also checks correctness, but sometimes the tests don't test the correct thing.  Whatever they test for becomes permanent.

 

Therefore, testing mathematical calculations is probably not a thing that should be tested for every possible outcome.

 

Correct.  You want to test enough to ensure the function is doing the right thing, but you don't need to test every value.  Often that means testing both sides of boundary conditions, and perhaps an easy to verify value in the middle.

 

Generally in test writing you have a test that hits the happy path -- doing everything right -- then a bunch of tests that excercse all the error conditions.  

 

Also another key about unit tests is that they need to be fast.  If they hit a database, hit a file system, hit a network, they are not a unit test they are an integration test.  

 

I think, it would help a lot if you could show me a simple example on how to invoke unit testing into a tiny code example using a class and whatnot.
 

 

It is Java rather than C++, but I've seen this tutorial used several times for starting to build Tetris using test driven development.

 

You will need to adjust it to your preferred testing framework, but that is generally easy to do.

 

There's also this amazing book that is freely available as a web site, less of a tutorial and more of a reference, it works through common patterns and struggles in automated tests.

Share this post


Link to post
Share on other sites

In case it wasn't clear above, your unit tests form part of a completely separate program. They reference the same classes, functions, and structures that your main program does, and perform tests to check that those objects behave as you expect. But they don't exist inside your main program, at all. Instead, you run the test program separately, to ensure that any recent code changes haven't broken any tests. You might even run it as a pre-build step if you have that capability, so that you don't waste time building your project if you've altered code in such a way that the tests now fail.

Share this post


Link to post
Share on other sites

Thanks a lot!

Telling me that it is an actual different program is already informing me a lot.

 

I'm really thankful for all of your comprehensive descriptions : )!!

 

One more question, I would have to create a new project in my solution and rebuild all my classes into one (or multiple) files?

Edited by Angelic Ice

Share this post


Link to post
Share on other sites

You don't have to touch your original files. You probably do want a separate project that contains the unit tests, and which can build an executable for those tests.

 

I don't know what you mean by "rebuild all my classes" but whatever you think you need to do here, you probably don't.

Share this post


Link to post
Share on other sites

Well, in order to test my classes, I would have to implement or rather copy them from the original project.

Is that right or is there any possibility to refer to my original files which saves rewriting/copying a class?

As the projects are separated, I doubt this is possible though.

Share this post


Link to post
Share on other sites

Multiple projects can refer to the same files - it's not like a directory where a file can only be in one at once.

 

How to do this depends on how you're building your projects. (Visual C++? Or...?)

Share this post


Link to post
Share on other sites

Well, in order to test my classes, I would have to implement or rather copy them from the original project.
Is that right or is there any possibility to refer to my original files which saves rewriting/copying a class?
As the projects are separated, I doubt this is possible though.

Typically you'd put the thing you want to test into a library project (static lib, dll, whatever).

You would then have an executable project that contains the tests and runs them (depending on the testing framework; some frameworks load dlls into a "test runner")

Finally you have your game executable which just loads your games library and starts it.

So in visual studio, something like
SuperAwesomeGame.sln
+ SuperAwesomeGameStuff (library)
- all your game code goes here
+ SuperAwesomeGame (exe)
- just basically has a "main" that starts your game
+ SuperAwesomeTests (exe)
- contains all the tests and runs them

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!