First TDD test with no assert/expected exception. Is it worth it?
Let's say I'm starting to do a game with TDD. Is this a good first test?
[TestMethod]
public void Can_Start_And_End_Game()
{
Tetris tetris = new Tetris();
tetris.Start();
tetris.End();
}
It basically forces me to define 3 things: the Tetris
class and its Start()
and End()
methods, but besides that it's p开发者_如何学运维retty useless. It might have its interest immediately as with them I can define that class and those methods, but later it probably won't serve any kind of purpose. Its only purpose would maybe show that it must be possible to start a game and end it without getting an exception in the middle.
What are your thoughts on that?
It basically forces me to define 3 things: the Tetris class and its Start() and End() methods,
True.
but besides that it's pretty useless.
False.
later it probably won't serve any kind of purpose
False, also.
Its ... purpose [is to] show that it must be possible to start a game and end it without getting an exception in the middle
And that's HUGE. Epic. Monumental.
Indeed, that test will fail so often that you'll grow to hate it. Every unhandled, uncaught exception from all kinds of random places in your program will fail this test. You'll build careful logging and debugging because of this test.
This test is EPIC.
You're not really driving development of the Tetris class with this test - you've decided what its API should be, which is fine, but why not write a test that tests something it should actually be doing?
The tests should inform the API, not vice versa (imho).
I'm not a big fan of this test. Yes it helped to define the interface, but it is not very strong for defining (and testing) behavior.
I think it might be better to have one test that handles the startup. It would probably assert the default settings or scoring values. Then I would have additional tests to see if you can end a game.
Ideally have each test method execute one behavior.
I think that the purpose of the test can be made clearer by catching any exceptions and explicitly failing the test if it happpens:
[TestMethod]
public void Can_Start_And_End_Game()
{
try
{
Tetris tetris = new Tetris();
tetris.Start();
tetris.End();
}
catch (Exception ex)
{
Assert.Fail("Unexpected exception thrown: " + ex.ToString());
}
}
Yes, the test confirms that no exception is thrown in the constructor, the Start()
and the Stop()
method.
I see little value in an a additional try/catch block within the test to catch exceptions. The tool executing the test will catch and report those. Using the principle TSTTCPW the test can do without the try/catch block.
You can make the test a little more meaningful by adding assertions at the end, for example validating the value of properties on the tetris
object.
Please be aware of the difference between writing a unit test and using TDD. The value comes from understanding that difference.
As S. Lott said, this test covers a TON of ground. It's so "worth it" that it's worth breaking up into at least 3 tests and adding appropriate assertions to each:
[TestMethod]
public void Test_Contructor()
{
Tetris tetris = new Tetris();
// make assertions
}
[TestMethod]
public void Test_Start()
{
// setup
Tetris tetris = new Tetris();
// exercise
tetris.Start();
// make assertions
}
[TestMethod]
public void Test_End()
{
// setup
Tetris tetris = new Tetris();
tetris.Start();
// exercise
tetris.End();
// make assertions
}
精彩评论