I just googled "Joshua Bloch TDD"... not much came up, which is a huge shame because I'd really like to know what he's got to say on the matter.
Item 13 (I'm looking at the 2nd edition) is entitled "Minimize the accessibility of classes and members". After a couple of pages he says:
To facilitate testing, you may be tempted to make a class, interface or member* more accessible. ... It is acceptable to make a private member of a public class package-private in order to test it, but it is not acceptable to raise the accessibility any higher than that... Luckily, it isn't necessary either, as tests can be made to run as part of the package being tested, thus gaining access to its package-private elements.
* by "members" he means "fields, methods, nested classes and nested interfaces".
As a TDD newb, but gradually finding my feet, I am aware that the current consensus seems to be not to include testing classes with the app code packages, nor even to have a matching structure under src\\test and src\\main: mostly TDD experts readily seem to structure their testing directories in other ways (eg you have one directory called "unittests" another called "functionaltests" and another called "e2etests").
Specifically, I have followed the TDD development of the auction app in "Growing Object Oriented Software Guided by Tests". The author there has no qualms about adding hundreds of public methods. Furthermore, after one chapter I looked at the downloaded "structure so far" and he had completely changed the testing directory structure to divide things into categories of test...
Is there any seasoned TDD hand out there who has, at least in the past, found this to be a source of dilemma? If so, how have you resolved it?
As a practical example, I'm cutting my teeth on TDD techniques by developing a Lucene index app: it indexes documents and then lets you query them. At the current time all the app classes are in the same package. The only method which actually needs to be public is main
in one class. And yet, of course, I have many, many public methods: they could all be package-private were it not for the fact that I am using TDD.
PS no tag for "method-visibility" so I chose "class-visibility"
later
It appears that I may have been led down a rather unfortunate path by the approach taken in "Growing Object-Oriented...", where the over-use of public methods was presumably used just because it's a demonstration of the technique. Ha.
If you want to split your categories of tests, does anyone ever use this sort of approach:
\\src\\unit_tests\\java\\core\\MainTest.java
but also, for example:
\\src\\func_tests\\java\\core\\MainTest.java
and
\\src\\e2e_tests\\java\\core\\MainTest.java
?
as tests can be made to run as part of the package being tested
This does not mean that you have to put your tests in the same directory as main classes, they just have to be in the same package which can very well be separate directory.
Assume you have a package com.acme.foo
. So your directory structure may be:
src
main
java
com
acme
foo
MainClass
test
java
com
acme
foo
MainClassTest
MainClassTest
is in the same package as MainClass
so it has access to package-private stuff. But these are separate directories, so your resulting JAR will not contain MainClassTest
.
I am not sure how this works in Gradle, as I am using Maven, but I imagine the concepts there are similar. Therefore I will explain it with Maven in mind. The typical setup in a Maven project looks like this:
On the root level of the projects there is src
and target
. Into the target
folder everything goes that is created during the build process. This means that src
contains the sources of our actual project. Under src
there are two other directories: main
and test
. Simply put into main
goes everything that will end up in the productive code, that will be delivered. The test
directory contains the test code for the main
tree.
Therefore it is usual that the same package hierarchy from the src/main/java
directory is also present in src/test/java
and therefore for a test class with the same package definition will have access to all members of the producive class which resides in the main
branch.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.