Should I change the naming convention for my unit tests?

后端 未结 7 2429
死守一世寂寞
死守一世寂寞 2021-02-20 04:45

I currently use a simple convention for my unit tests. If I have a class named \"EmployeeReader\", I create a test class named \"EmployeeReader.Tests. I then create all the test

相关标签:
7条回答
  • 2021-02-20 05:22

    The naming convention I've been using is:

    functionName_shouldDoThis_whenThisIsTheSituation

    For example, these would be some test names for a stack's 'pop' function

    pop_shouldThrowEmptyStackException_whenTheStackIsEmpty

    pop_shouldReturnTheObjectOnTheTopOfTheStack_whenThereIsAnObjectOnTheStack

    0 讨论(0)
  • 2021-02-20 05:28

    i vote for calling the test case class: EmployeeReaderTestCase and calling the methods() like http://xunitpatterns.com/Organization.html and http://xunitpatterns.com/Organization.html#Test%20Naming%20Conventions

    0 讨论(0)
  • 2021-02-20 05:30

    Part of the reasoning behind the 2nd naming convention that you reference is that you are creating tests and behavioural specifications at the same time. You establish the context in which things are happening and what should actually then happen within that context. (In my experience, the observations/test-methods often start with "should_," so you get a standard "When_the_invoicing_system_is_told_to_email_the_client," "should_initiate_connection_to_mail_server" format.)

    There are tools that will reflect over your test fixtures and output a nicely formatted html spec sheet, stripping out the underscores. You end up with human-readable documentation that is in sync with the actual code (as long as you keep your test coverage high and accurate).

    Depending on the story/feature/subsystem on which you're working, these specifications can be shown to and understood by non-programmer stakeholders for verification and feedback, which is at the heart of agile and BDD in particular.

    0 讨论(0)
  • 2021-02-20 05:31

    I use second method, and it really helps with describing what your software should do. I also use nested classes to describe more detailed context.

    In essence, test classes are contexts, which can be nested, and methods are all one line assertions. For example,

    public class MyClassSpecification
    {
        protected MyClass instance = new MyClass();
    
        public class When_foobar_is_42 : MyClassSpecification 
        {
            public When_foobar_is_42() {
                this.instance.SetFoobar( 42 ); 
            }
    
            public class GetAnswer : When_foobar_is_42
            {
                private Int32 result;
    
                public GetAnswer() {
                    this.result = this.GetAnswer();
                }
    
                public void should_return_42() {
                    Assert.AreEqual( 42, result );
                }
            }
        }
    }
    

    which will give me following output in my test runner:

    MyClassSpecification+When_foobar_is_42+GetAnswer
        should_return_42
    
    0 讨论(0)
  • 2021-02-20 05:32

    I've been down the two roads you describe in your question as well as a few other... Your first alternative is pretty straight forward and easy to understand for most people. I personally like the BDD style (your second example) more because it isolates different contexts and groups observations on those contexts. Th only real downside is that it generates more code so starting to do it feels slightly more cumbersome until you see the neat tests. Also if you use inheritance to reuse fixture setup you want a testrunner that outputs the inheritance chain. Consider a class "An_empty_stack" and you want to reuse it so you then do another class: "When_five_is_pushed_on : An_empty_stack" you want that as output and not just "When_five_is_pushed_on". If your testrunner does not support this your tests will contain redundant information like: "When_five_is_pushed_on_empty_stack : An_empty_stack" just to make the output nice.

    0 讨论(0)
  • 2021-02-20 05:34

    Your second example (having a fixture for each logical "task", rather than one for each class) has the advantage that you can have different SetUp and TearDown logic for each task, thus simplifying your individual test methods and making them more readable.

    You don't need to settle on one or the other as a standard. We use a mixture of both, depending on how many different "tasks" we have to test for each class.

    0 讨论(0)
提交回复
热议问题