aspose file tools*
The moose likes Testing and the fly likes unit testing class name preferences: TestCow vs. CowTest Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Engineering » Testing
Bookmark "unit testing class name preferences: TestCow vs. CowTest" Watch "unit testing class name preferences: TestCow vs. CowTest" New topic
Author

unit testing class name preferences: TestCow vs. CowTest

paul wheaton
Trailboss

Joined: Dec 14, 1998
Posts: 20271
    ∞

prefix: TestCow
  • tests are in the same dir, they are seperated in a directory view - easy to find files without having to pick through the tests.
  • Easier to pick files in an IDE - Typing "Co" would bring up just "Cow" instead of "Cow" and "CowTest"


  • postfix: CowTest
  • if tests are in the same dir, they are mixed in a directory view - easy to spot classes with no test.
  • More OO - class name is more of a noun (object) than a verb (procedural).


  • What is your preference?
    [ April 14, 2003: Message edited by: Paul Wheaton ]

    permaculture Wood Burning Stoves 2.0 - 4-DVD set
    Max Habibi
    town drunk
    ( and author)
    Sheriff

    Joined: Jun 27, 2002
    Posts: 4118
    1. It's more JUnit friendly.
    M, author
    The Sun Certified Java Developer Exam with J2SE 1.4


    Java Regular Expressions
    Jim Yingst
    Wanderer
    Sheriff

    Joined: Jan 30, 2000
    Posts: 18671
    [Max]: 1. It's more JUnit friendly.
    It is? We're talking about class names, not method names, right? Most examples I've seen for JUnit class names end in Test, indicating that they extend TestCase (which paradoxically doesn't end in Test, but it's the exception). Am I missing something?
    I prefer CowTest over TestCow, as CowTest sounds like a noun, as it should. Paul's other concerns can be alleviated by putting the test classes in a separate directory as God intended.
    One other problem with TextCow is that, while it does put all the Test stuff in one place when you sort by alphabetical order, it also may encourage you to overlook some non-test stuff if it begins with U, V, W, X, Y, Z. Or quite a few possible T words as well. Cleaner and more reliable to just create a separate namespace if that's what you want. Plus, I see at least as much benefit in putting CowTest next to Cow as I do in putting TestCow next to TestDog.
    [ April 14, 2003: Message edited by: Jim Yingst ]

    "I'm not back." - Bill Harding, Twister
    Frank Carver
    Sheriff

    Joined: Jan 07, 1999
    Posts: 6920
    I'd use CowTest.
    More than that, I've taken to putting all my tests into a "tests" package for at least the last couple years now. It's great, I can re-use tests between projects (and test utilities, such as dumping maps, count an iterator etc.) just by copying.
    More than that, I've taken to putting the tests under a completely different directory structure so ant knows not to build them into the deliverable:
    /appname
    | /src
    | | /delivery
    | | | /java
    | | | | /com
    | | | | | /efsol
    | | | | | | /appname
    | | | | | | | Foo.java
    | | | | | | | Bar.java
    | | | /files
    | | | | index.html etc.
    | | /test
    | | | /java
    | | | | /tests
    | | | | | AllTests.java
    | | | | | CowTest.java
    | | | | | TestUtils.java
    | | | /files
    | | | | foo.prp
    | | | | bar.prp
    | build.xml
    /build
    /lib
    Mixing in the test cases with the delivered code seems like a configuration management nightmare to me!
    [ April 14, 2003: Message edited by: Frank Carver ]

    Read about me at frankcarver.me ~ Raspberry Alpha Omega ~ Frank's Punchbarrel Blog
    Jessica Sant
    Sheriff

    Joined: Oct 17, 2001
    Posts: 4313

    we do similar to Frank.... except you basically recreate the package structure of the "src" in the "test" folder -- that way your tests will have access to protected/pacakge methods and you can make your tests more fine-grained... so in our scenario the environment looks like this:
    /appname
    | /src
    | | /delivery
    | | | /java
    | | | | /com
    | | | | | /efsol
    | | | | | | /appname
    | | | | | | | Foo.java
    | | | | | | | Bar.java
    | | | /files
    | | | | index.html etc.
    | | /test
    | | | /java
    | | | | /com
    | | | | | /efsol
    | | | | | | /appname
    | | | | | | | FooTest.java
    | | | | | | | BarTest.java
    | | | /files
    | | | | foo.prp
    | | | | bar.prp
    | build.xml
    /build
    /lib
    Randall Twede
    Ranch Hand

    Joined: Oct 21, 2000
    Posts: 4339
        
        2

    i cant really speak to the actual question but i do want to comment on which sounds more like a noun. to me, a test cow is the cow you use for testing purposes. a cow test is a test that you make a cow perform. which sounds more like a noun to you?


    SCJP
    Visit my download page
    Frank Carver
    Sheriff

    Joined: Jan 07, 1999
    Posts: 6920
    we do similar to Frank.... except you basically recreate the package structure of the "src" in the "test" folder -- that way your tests will have access to protected/pacakge methods and you can make your tests more fine-grained
    I used to do that, but I found it very clumsy. I seemed to be always fiddling around changing package statements in the test code whenever I created a new project or moved/renamed packages inside the application.
    I have also found that I dislike designing or working on code where you need to be in the same package to test it. For me, things that are testable should be public. If I find I need to test something which is private or protected, then I either make it public (if it can't leave the object in an inconsistent state), or split the class into smaller ones which are testable using their public interface.
    I also found that putting the test code in the same package as some of the code usually means that it is not in the same package as some other code. I like to be free in my my test code to test user operations (typically using objects of several classes at once), not to be tied to just testing the methods of one class or one package.
    Have you not encountered any of these problems?
    Ilja Preuss
    author
    Sheriff

    Joined: Jul 11, 2001
    Posts: 14112
    Originally posted by Frank Carver:
    Mixing in the test cases with the delivered code seems like a configuration management nightmare to me!

    Unless you don't mind delivering your test code. Sometimes it can be very handy to run the test suite at the customers installation site - you might find some of the tests failing because of a slightly different JDK installed...


    The soul is dyed the color of its thoughts. Think only on those things that are in line with your principles and can bear the light of day. The content of your character is your choice. Day by day, what you do is who you become. Your integrity is your destiny - it is the light that guides your way. - Heraclitus
    Ilja Preuss
    author
    Sheriff

    Joined: Jul 11, 2001
    Posts: 14112
    Originally posted by Frank Carver:
    I have also found that I dislike designing or working on code where you need to be in the same package to test it. For me, things that are testable should be public. If I find I need to test something which is private or protected, then I either make it public (if it can't leave the object in an inconsistent state), or split the class into smaller ones which are testable using their public interface.

    I totally agree!
    Ilja Preuss
    author
    Sheriff

    Joined: Jul 11, 2001
    Posts: 14112
    Originally posted by Randall Twede:
    to me, a test cow is the cow you use for testing purposes. a cow test is a test that you make a cow perform.

    Agreed. TestCow sounds very much similar to a DummyCow, MockCow etc.
    CowTest sounds like (a) Test(s) for a cow.
    Matthew Phillips
    Ranch Hand

    Joined: Mar 09, 2001
    Posts: 2676
    I like CowTest for the very reason that the name is descriptive of a test that I am giving to a cow. I generally do my directory structure the same way Frank does.


    Matthew Phillips
    Nathan Pruett
    Bartender

    Joined: Oct 18, 2000
    Posts: 4121

    I prefer CowTest too.

    As another option in the "how to set up directories for test cases" argument, I've been on projects that have used both approches to unit testing. Some put unit tests in another package totally ( i.e. "package test.com.whatever.stuff;" ), this is good if you only need (or want) to test the public interfaces. Some put them in a directory called test and had the same package structure as the code they were testing, this lets you call package private and protected methods. One project also made all the test cases inner classes of the classes they tested. This let them test any method of the class. When it was time for a final build, there was an extra Ant task that went through the build directory and deleted all "*Test.class" files before the build was packaged.


    -Nate
    Write once, run anywhere, because there's nowhere to hide! - /. A.C.
    Frank Carver
    Sheriff

    Joined: Jan 07, 1999
    Posts: 6920
    One project also made all the test cases inner classes of the classes they tested.
    I've seen this too, but usually accompanied by a misunderstanding of what testing is about. These "embedded test cases" were typically full of copy-n-pasted tests of accessors/mutators, and usually one test method for each of the real methods of the class. Unfortunately, this often lead to a sort of "test blindness" where the vital tests of the integration between objects in a wider context were ignored.
    It also has the unfortunate side effect that source files can become swamped with huge amounts more test code than "real" code, making it much harder to find things and complicating the version control process. May I suggest that if the "real" code were to grow that big, we would consider factoring it out into separate classes. So why should "test" code be exempt from that pressure?
    Thomas Paul
    mister krabs
    Ranch Hand

    Joined: May 05, 2000
    Posts: 13974
    It also has the unfortunate side effect that source files can become swamped with huge amounts more test code than "real" code, making it much harder to find things and complicating the version control process.
    I agree that test code should not be in an inner member class but not for this reason. The whole idea of an inner member class is to isolate chunks of code. There is no reason that an inner member class can't simply be moved to the bottom of your class.
    The advantage of the inner member class for testing is that it forces you to keep it up to date (somewhat) because if you change method names or variable names your code doesn't compile anymore.


    Associate Instructor - Hofstra University
    Amazon Top 750 reviewer - Blog - Unresolved References - Book Review Blog
    Jessica Sant
    Sheriff

    Joined: Oct 17, 2001
    Posts: 4313

    Just thought I'd add some comments from another source... Right now I'm reading O'Reilly's Java Extreme Programming Cookbook.
    Recipe 4.10 covers Test Naming Conventions:
    They argue that they prefer TestCow rather than CowTest. They use IntelliJ and find that its easier to search for all test cases when they all start with the word "Test" -- they see the main advantage of naming things like CowTest is so you can easily see which classes don't have associated Test Cases.
    They also comment on my practice of having a seperate, parallel directory structure for all Test Cases. They think this is a bad idea 'cause you have to look in two locations to see the tests, and they add you can easily exclude all Test Cases from being included in a build using Ant's <exclude name="**/Test*.java"/> command
    Greg Charles
    Sheriff

    Joined: Oct 01, 2001
    Posts: 2771
        
      10

    O'Reilly authors notwithstanding, I like having the separate parallel directory structure for test cases. I use JBuilder and this is its preferred structure as well. I'm not sure I understand their criticism. You have to look in two places for test code? No, you only look in the test directory. True, the code you're testing is in a different directory, but so what? It's going to be in a different file anyway.
    As for TestCow vs. CowTest, I have tended to TestCow, but after reading this thread, I think CowTest makes more sense. Another consideration is if your test used inner classes. (OK, maybe its not likely, but it could happen.) An Ant pattern **/Test*.class would still match TestCow$InnerClass.class, but **/*Test.class wouldn't match CowTest$InnerClass.class. Presumably, your inner class wouldn't be a JUnit Test*, so that's another argument for CowTest.

    * If it were, you could call it InnerClassTest and the pattern would still work.
    Ilja Preuss
    author
    Sheriff

    Joined: Jul 11, 2001
    Posts: 14112
    Originally posted by Jessica Sant:
    They argue that they prefer TestCow rather than CowTest. They use IntelliJ and find that its easier to search for all test cases when they all start with the word "Test"

    I don't remember to ever have wanted to do this. Why would you?
    If you would want to, there are certainly other strategies to get the same result, too. What about searching for "extends TestCase", or using Eclipses "Type Hierarchy" view?
    they add you can easily exclude all Test Cases from being included in a build using Ant's <exclude name="**/Test*.java"/> command

    Of course that would also exclude Testosterone.java ... :roll:
     
    It is sorta covered in the JavaRanch Style Guide.
     
    subject: unit testing class name preferences: TestCow vs. CowTest
     
    Similar Threads
    Runtime.exec()
    Problem in File Browser