I feel that test methods should be placed right under the methods they are supposed to test. But in tutorials I found so far they only placed in [TestClass]es inside Unit Test Projects. Why is that necessary?
-
*Questions asking us to recommend or find a book, tool, software library, tutorial or other off-site resource are off-topic for Stack Overflow* – EZI Jul 31 '15 at 06:40
-
If you put them below the methods they are supposed to test, you'd have to deploy all your tests when releasing your software, which if far from necessary. You'd also need to tight couple the classes from your program to your test library. Long story short, not a good idea – xlecoustillier Jul 31 '15 at 06:44
-
*EDITED.* But you got an idea, question reading people? – Borbon Hause Jul 31 '15 at 06:44
-
@X.L.Ant Hum, C# doesn't automatically remove unused methods? C++ compiler probably could, if I remember correctly... What if I want to test a private method of a class? Maybe it's a dumb idea too, because incapsulation and stuff... – Borbon Hause Jul 31 '15 at 06:46
-
@BorbonHause no, the compiler doesn't do that, AFAIK. If it tried to do that, how would it know that you don't use those methods, let's say, using reflection ? See http://stackoverflow.com/a/5204759/1679537 – xlecoustillier Jul 31 '15 at 06:48
1 Answers
Why would you want to use [TestMethod] outside the Unit Test project? The idea of [TestMethod] is to mark it as a method to be unit tested.
Normal best practice is to have your Unit Tests in a separate project. I believe it was Roy Osherove who recommended that you setup your unit tests like this:
Each project has a unit test project called YourProjectName.Tests (can further be broken into YourProjectName.UnitTests and YourProjectName.IntegrationTests if desired)
Each class or unit of work to be tested should have its own file in the unit test project named something like YourClassNameUnitTests
Each method or unit of work to be tested needs to be labelled with [TestMethod] or similar and you should use descriptive names like
public void MethodName_ScenarioUnderTest_ExpectedBehaviour()
To specifically answer your question, if you have [TestMethod] under the method itself you will make things very difficult to manage because:
When you have 100's of tests you will have to look all over the place to find them
Your tests will get mixed up in your production code instead of being separate (when they're a separate project you can release your production code without a ton of unit tests in them)
Someone who comes along after you to maintain the tests will much appreciate being able to look at one file for a class and see all the tests instead of having to scroll a production class full of methods > test methods > more methods > more test methods.
This also makes the unit tests very hard to maintain. If you ever need to move unit tests for any reason, imagine how difficult it will be if your unit tests aren't in one file? If you do it how you describe, you will have to go through tests one by one cutting and pasting because you can't just select a bunch at once.
Hope that helps.

- 878
- 2
- 11
- 22
-
Awesome, thank you, but just a little question. What you meant by "moving tests"? – Borbon Hause Jul 31 '15 at 06:56
-
Sorry, I was just trying to give another example of why putting tests in your production code could make them very hard to maintain. If you ever needed to copy your unit tests from one file to another file, you can easily copy & paste them if the unit tests are in a file of their own. But if you have your tests in a production class so you have method > test method > another method > another test method, then you can't copy your unit tests like that because you will get your production code as well. Instead you'd have to go through the tests one-by-one and manually copy them individually. – Calcolat Jul 31 '15 at 07:02
-
Hm... You know, if we had a proper tools, this movement would require like 5 lines of code. Something like ForFile("MyClass.cs").ForMethod.If( HasAttribute(TestMethod), MoveMethodToFile("OtherClass.cs"). I wonder if somebody written something like this already. – Borbon Hause Jul 31 '15 at 07:26
-
Yes you're correct. Technically you could write something to do that. But the point I was trying to make is why go to all that effort when there's an easier way to structure your tests? If you find yourself having to resort to doing things like that, it's usually a sign your design might need to be reviewed. If a project ends up with hundreds or thousands of tests, one of the biggest keys is making sure that mountain of tests will still be maintainable in the future. The less effort someone needs to put into maintaining the tests, the better. – Calcolat Jul 31 '15 at 07:38
-
Um, I see. Sorry for taking your time. Never seen real unit tests, so I can only guess on the tests per code proportions. – Borbon Hause Jul 31 '15 at 07:42
-
That's okay. I guess the key is to try and make your tests as maintainable as possible. Imagine you write some code for a company and leave. Then 3 years later some new guy has to work with your code. If the new guy can just look at one test class and see all your tests that's easy. If he has to go scrolling through production code to find them, that's not so easy. If he has to start using code hacks to get what he wants then that's even worse. But that's just one reason... as I touched on above there's also some other reasons why it's best to separate tests from your project. – Calcolat Jul 31 '15 at 07:50
-
Also this is my opinion now... but if you're new to unit testing you can check out Roy Osherove's website at http://artofunittesting.com/ His got a lot of free videos there that might help you. His book on unit testing in .NET is golden as well. – Calcolat Jul 31 '15 at 07:53