views:

180

answers:

7

What exactly is a unit test and how do I write one? I hear many times people write them before their app is even written, how can this be? I am under the impression that a unit test is some code that makes a call to a method of your app with a set value and expects a specific value to come back, if the specific value does not come back the test has failed. Am I wrong or mislead here? I read so much about unit testing this and that but I know very little about what it actually looks like in code so a sample would be great.

Is this a unit test?

start psuedo code...

CheckForDuplicateSubdomains(){
get all users in DB with matching subdomains
if greater than zero, fail test
}

PS: I am using ASP.NET MVC in C#

+1  A: 

I am under the impression that a unit test is some code that makes a call to a method of your app with a set value and expects a specific value to come back, if the specific value does not come back the test has failed. Am I wrong or mislead here?

Nope, you are exactly right.

The important thing with unit tests is to test a small a piece of code as possible.

In your example you get something from the db and then count the number of items... If your method fails, you'll never know exactly where the things went wrong because there is so much that could go wrong....

Your db-connection could be lost, sql invalid, ...

If you are using asp.net MVC, you should have an easier time writing unit tests than if you were using normal asp.net

Quagmire
+1  A: 

A Unit Test is a test that exercises a very small portion of your code, usually a single method (a Unit to be exact).

In TDD, developers are able to write the Unit Test before coding the method because they already know what the Unit of code should do. It doesn't matter how it does the work...the test just makes sure the results are correct.

And that pseudo-code could be used as a Unit test (not sure what it would be testing, but I would have to assume you're testing a method that shouldn't return duplicate SubDomains).

The theory is Unit Testing (and Test Driven Development) should alleviate headaches further down the road by making sure each Unit of code does exactly what is expected of it.

Justin Niessner
+8  A: 

You are correct about unit testing. The idea is to test all your functions, one by one, with different inputs to make sure they work like you expect (as opposed to finding out after they've been inserted into an application.. and then making the testing more complicated).

Writing the unit tests before you write the function is part of a methodology called "Test driven development". In which you write the skeleton of the function only, and all the unit tests first. So at first all your tests will fail (b/c the function is not programmed yet). After that you program the function until all the tests pass.

Nestor
TDD involves writing a single unit test, then the code to make it pass, then refactoring that code to clean it up, and finally repeating with a new unit test. You wouldn't write a bunch of tests, then a bunch of code as you seem to imply.
ColinD
I don't think TDD precludes writing more than one test at a time, though maybe I'm ignorant on that matter. For example, what if the function must do two things -- for example, insert a row into a database and return the row number. That might require two tests, one to test that the row is entered, and a second test to show that the row number is correct. Of course, you could do both validations in a single test, but at this point we're splitting hairs on the definition of what makes up a single test.
Bryan Oakley
Ref: http://agileinaflash.blogspot.com/2009/07/essential-unit-test-cards.htmlYou only write enough of a test to get a failure, then only enough code to get it to pass, then enough to get another failure. Think of it as writing a spec, then enough code to fulfill the spec. When you see the code, you realize that you need a better spec, and each spec leads to better code. At the end, the tests show all cases you considered and are good reading for the next guy in.
tottinge
A: 

I'd check out this SO post related to unit testing and ASP.NET. It has a bunch of links and some commentary about the subject.

itsmatt
+1  A: 

Yes, your example would be a unit test. There are a few reasons to create the test first. First, it acts as living documentation for your project. It establishes behaviors and expected outcomes, which should help you actually implement your code (it's easier to write something, knowing what it needs to do and basically how it is initiated). Secondly, if you write the test afterward, you're more likely to write a test that works with the code you already wrote, which doesn't help you. Define what a unit of code needs to do, write the tests, and write/fix the code so it reflects the behaviors in the tests. This strategy translates into improved understanding and quality as your application evolves.

HackedByChinese
+1  A: 

Unit testing is automated testing at the Unit level. By unit level they mean atomic code unit such that you can't break it down further. a function or a particular part of an object. a unit test for a square function would look something like

 assertEqual(4, square(2));
 assertEqual(4, square(-2));
 assertEqual(0, square(0));

Now you can write this as soon as you have decided on the interface of square, for a more complicated function you could measure how close to complete the function is by how many tests pass.

stonemetal
A: 

There are very well established conventions for unit testing in the xUnit family of frameworks, originally derived from jUnit. In that framework, the assertion is the main vehicle for making a test. In a test suite, the objective is to ensure that 100% of your assertions are true.

Consider your example.

CheckForDuplicateSubdomains(){
  get all users in DB with matching subdomains
  if greater than zero, fail test
}

This test would conventionally have a name starting with "test", which lets the framework's test runner know that this function is a test and not a setup method, say. It is important to be clear that we are testing the behavior of the code, and not the state of the data.

testNoDuplicateSubdomains(){
}

Within each test, there are four phases:

  • fixture setup,
  • exercise SUT,
  • result verification and
  • fixture teardown.

The SUT is the "system under test", which is typically one method of a class in your production code.

testNoDuplicateSubdomains(){
  // fixture setup
  prepareDatabaseTestData()
  // exercise SUT, 
  SUT = new ProductionObject()
  result = SUT.getAllUsersWithMatchingSubDomains()
  // result verification and 
  assertEmpty(result) // or whatever makes sense
  // fixture teardown.  
  removeDatabaseTestData()
}

As with many software development techniques, it takes a while to get experienced at writing unit tests. A good resource for learning the best practices is xUnit Test Patterns by Gerard Meszaros.

Ewan Todd
It seems like there is a misconception in the OP's example CheckForDuplicateSubdomains() in that it appears to be tilted towards verifying the state of some data rather than the behavior of some code block. Even though I have carried that into my modified example, I believe the discussion is still informative. As a an aside, I would recommend that a beginner prefer to gain experience constructing unit tests in a piece of the code that is not close to the database. The code-database interface is a notoriously troublesome piece to unit test.
Ewan Todd