1. Test names must be strings
We need to start by saying that the name of the test is the name of the function. Unlike functions, we do not call tests from the code; the name of the test is only needed to describe what it tests once, so that this description is then written to the log with the test results.
Therefore, in some test frameworks, test names are regular strings.
For example in Catch (C ++)
TEST_CASE("что-то когда такие-то условия") { auto testee = Testee(1, 2); REQUIRE(testee.foo() == 1); }
Or Mocha (JS and other * script)
describe('что-то', function () { it('когда такие-то условия', function () { var testee = Testee(1, 2); assert.equal(testee.foo(), 1); }); });
An interesting exception is languages where identifiers can have any characters, such as in F #
[<Test>] let ``twice удваивает числа`` () = twice(1) |> should equal 2
2. No need to repeat (DRY principle)
If the test framework allows you to group tests, then this should be used. Instead of tests Чтото_КогдаЭто_ВотЭто , Чтото_КогдаДругое_ВотЭто and Чтото_КогдаДругое_ЕщеИЭто tests can be grouped.
Mocha / JS example:
describe('что-то', function () { var testee = Testee(); describe('когда так-то', function () { it('вот это', function () { testee.setup(1); assert.equal(testee.f(), 1); }); }); describe('когда по другому', function () { testee.setup(2); it('вот это', function () { assert.equal(testee.f(), 20); }); it('и еще это', function () { assert.equal(testee.g(), 21); }); }); });
Or for Catch / C ++:
TEST_CASE("что-то") { auto testee = Testee(); WHEN("когда так-то то вот это") { testee.setup(1); REQUIRE(testee.f() == 1); } WHEN("когда по другому") { testee.setup(2); THEN("вот это") { REQUIRE(testee.f() == 20); } THEN("и еще это") { REQUIRE(testee.g() == 21); } } }
It also often does not make sense to repeat the test code in the test name. It is necessary to describe what the test checks, and not how it does it. Therefore, instead of StartButton_WhenPressed_BecomesDisabled, you can write
TEST_F(ButtonsPanelTest, StartButtonPress) { EXPECT_CALL(delegate_mock, Start()); start_button.Press(); ASSERT_FALSE(start_button.IsEnabled()); }
Typically, the test includes the initial conditions (GIVEN / WHEN part) and the results (THEN part). If for some initial conditions there is one test, then why not write in the title what is checked in the THEN part. This is evident from the code, and if the test fails, the text of the failed check will be written in the log.
Test Name Examples
Test names depend on the test framework and on the test level (unit / integration / regression).
Mocha / JS Regression Tests
describe("File IO", function() { it("can read text", function() {...}) it("invalid file name error", function() {...}) it("read after EOF error", function() {...}) })
Unit tests on Catch / C ++, when Catch uses split test names /
TEST_CASE_METHOD(ParserFixture, "Notifications/Empty") { SECTION("no 'type' field") {...} SECTION("empty updates") {...} } TEST_CASE_METHOD(ParserFixture, "Notifications/Status update") {...} TEST_CASE_METHOD(ParserFixture, "Notifications/Profile update") {...}
Newer Catch / C ++ tests tagged
TEST_CASE("request line", "[http][parser]") {...} TEST_CASE_METHOD(FrameReceiverFixture, "is frame complete", "[websocket]") {...}
Tests for gtest / C ++ (from Chromium code)
TEST_F(DownloadItemTest, CompleteDelegate_SetDanger) {...} TEST_F(DownloadItemTest, NotificationAfterOnDownloadTargetDetermined) {...}
Tests on Golang
func TestSomeClassMethod_CanDoThis(t *testing.T) {...}
If the test name cannot be specified as a string, then the simultaneous use of CamelCase and underscore gives a fairly good readability. For example, instead of TEST_CASE("some unit") { WHEN("this state") { THEN("those results") { ... you can write SomeUnit_WhenThisState_ThoseResults .