Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Automated testing feels a lot like duplicating the tested logic, am I doing it right?

I'm implementing automated testing with CppUTest in C++.
I realize I end up almost copying and pasting the logic to be tested on the tests themselves, so I can check the expected outcomes.
Am I doing it right? should it be otherwise?

edit: I'll try to explain better:
The unit being tested takes input A, makes some processing and returns output B
So apart from making some black box checks, like checking that the output lies in an expectable range, I would also like to see if the output B that I got is the right outcome for input A I.E. if the logic is working as expected.
So for example if the unit just makes A times 2 to yield B, then in the test I have no other way of checking than making again the calculation of A times 2 to check against B to be sure it went alright.
That's the duplication I'm talking about.

// Actual function being tested:  
int times2( int a )
{
  return a * 2;
}

.

// Test:
int test_a;
int expected_b = test_a * 2; // here I'm duplicating times2()'s logic
int actual_b = times2( test_a );
CHECK( actual_b == expected_b );

.

PS: I think I will reformulate this in another question with my actual source code.

like image 708
Petruza Avatar asked Dec 04 '25 19:12

Petruza


2 Answers

If your goal is to build automated tests for your existing code, you're probably doing it wrong. Hopefully you know what the result of frobozz.Gonkulate() should be for various inputs and can write tests to check that Gonkulate() is returning the right thing. If you have to copy Gonkulate()'s convoluted logic to figure out the answer, you might want to ask yourself how well you understand the logic to begin with.

If you're trying to do test-driven development, you're definitely doing it wrong. TDD consists of many quick cycles of:

  1. Writing a test
  2. Watching it fail
  3. Making it pass
  4. Refactoring as necessary to improve the overall design

Step 1 - writing the test first - is an essential part of TDD. I infer from your question that you're writing the code first and the tests later.

like image 143
Edmund Schweppe Avatar answered Dec 06 '25 09:12

Edmund Schweppe


So for example if the unit just makes A times 2 to yield B, then in the test I have no other way of checking than making again the calculation of A times 2 to check against B to be sure it went alright.

Yes you do! You know how to calculate A times two, so you don't need to do this in code. if A is 4 then you know the answer is 8. So you can just use it as the expected value.

CHECK( actual_b == 8 )

if you are worried about magic numbers, don't be. Nobody will be confused about the meaning of the hard coded numbers in the following line:

CHECK( times_2(4) == 8 )

If you don't know what the result should be then your unit test is useless. If you need to calculate the expected result, then you are either using the same logic as the function, or using an alternate algorithm to work out the result.In the first case, if the logic that you duplicate is incorrect, your test will still pass! In the second case, you are introducing another place for a bug to occur. If a test fails, you will need to work out whether it failed because the function under test has a bug, or if your test method has a bug.

like image 22
saus Avatar answered Dec 06 '25 09:12

saus



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!