Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 1 year ago.
Improve this question
I am a college student that makes his programs here and there in C#, mostly scientific simulations. Is there any use in learning NUnit?
I keep hearing people talking about it but I don't fully grasp what it is in the first place. Is it something that every programmer should use, or something that is more suited for big projects with lots of people?
Testing is a vital part of writing software - any kind of software. Whether you are writing a little routine to sort numbers, or a system to launch space ships to Mars.
Now it used to be that developers would write their code, and then exercise it by hand - often in a debugger - to verify that it did what they expected. This was a painful and tedious way to test their code. Not only was it tedious and painful - but it wasn't repeatable. This meant that every time you made a change you had to manually repeat the tests and hope you didn't forget anything or do things slightly differently. Quality suffered - and there was much sorrow and weeping.
Eventually, developers realized that they could write a separate program that would exercise their code by running it through the conditions that they expected it to handle, and having that code verify the results. Things started to get better. This approach to testing was often called a test harness.
Writing test harnesses helped, but there was a lot of repetitive code - there is quite a bit of infrastructure related to running and verifying tests. However, some really smart developers out their said: "We're not going to write boiler plate code over and over ... we'll make a library to do it for us." And so unit testing tools like JUnit and NUnit (and many others) were born.
These libraries (and tools) help you structure, organize, and execute your tests. They provide convenient methods to verify conditions, trap and trace exceptions, and report which tests passed and which ones failed. Finally, developers could focus on the important part: writing the tests and verification logic that would help assure that the code they wrote worked. These tests were repeatable. They could be run as part of an automated build process. They could be handed down through the generations and added to by others as new failure points were found and fixed. They could be re-run by the original developer months and years after the original code had been written to make sure things still work.
If you plan to be a successful software developer at any level, in any size organization (even if it's just yourself) - you should learn about - and embrace unit testing.
Here are some resources to help you on your way:
NUnit Documentation and Samples
The Art of Unit Testing
Unit Testing Best Practices
Write Maintainable Unit Tests That Will Save You Time And Tears
Yes you should use it. (or any test runner)
Testing is quite an important part of programming (In my opinion), so if you (or someone else) changes a part of code, and it happens to break something down the line, your tests should pick this up.
Well, that's how I see it, I'm still new to unit testing.
An Example.
Lets say I have a method
Add(int a, int b)
{
return a + b;
}
My Unit Test would be:
[Test]
public void Test001_TestAdd()
{
Assert.IsTrue(Add(1,3) == 4);
}
If someone changed the Add Method to lets say:
Add(int a, int b)
{
return a * b;
}
My Unit test would fail, and could potentially save a life (if you work in medical software, or for NASA), or stop a potential bug :)
Now if they had Unit Tests, this may not have happened, simple problem, missed.
Absolutely. Unit testing is one of the most important concepts to learn in modern software development.
It doesn't matter if your programs are scientific simulations, enterprise applications, etc. neither if you are in a big team or if you code alone (but in big teams is as important as compiling your code).
A good book to start on unit testing (for .net) is Pragmatic Unit Testing in C# with NUnit
Every programmer should learn it. Now, will every programmer use it? Likely not, but they should know it anyway.
Unit testing is very, very common nowadays, and understanding how it works is essential in any project other than the little hobby ones you're writing right now. Use the time you have now and get ready for your future. Also learn about Mock objects (related).
Unit testing has many values, depending on what you do and what projects you work on different parts of unit testing will be important to you.
At very least you should learn the basics of unit testing to have a fully rounded sense of the development process. As time goes on and you work on larger projects you will find that unit testing is an integral part of maintaining and growing large codebases.
NUnit is an excellent tool if you're interested in Test-Driven Development.
See my answer here for some notes about TDD.
I've found that if you can get a ReSharper license (Visual Studio plug-in that does many things) that the running of unit tests becomes so quick and easy that writing them really does become a no-brainer, even for small pieces of work.
Related
Is TDD good approach for small and short projects done by small teams up to 4 people ? Is that really a profitable effort ?
What about Unit Testing ? TDD implies Unit Testing but no conversely. Wouldn't be Unit Testing sufficient, done from time to time during the project development life cycle, until reasonable code coverage ?
For me, it doesn't boil down to whether the project is small or short. TDD, done correctly, is about being able to quickly run a set of tests that provide full confidence in the code. There also has been a lot written about TDD helping to drive out the appropriate design for projects as well.
So, you could argue that TDD is best on small and short projects because you end up only writing the code that you need to make the tests pass and nothing else. Therefore, keeping the cost down. Then, there is the added benefit of having confidence in the tests and code when you make changes later.
The next small point I would make is that a lot of projects start small and short. These interim solutions have a way of becoming strategic platforms for development (if successful).
Recently I've read nice blog post from Szymon Pobiega, titled If you are not doing TDD…. I really encourage to take a look on this. It's because I'm a bit skeptical about TDD and placing it into great habits of development life cycle, as an ultimate solution for your projects safety, apart from the nature of the project. I like this fragment:
TDD is most useful when you have absolutely no idea about the shape of
the code. In such case you better not hack the code as fast as you
can. Rather then make one small step at a time, each time validating
the outcome. Ideally, do it in a pair. Each step you make allows you
to discover more tests that need to be written. I love the analogy Dan
used in his presentation: it’s just like swimming versus walking in
1.50 meter deep pool. You can walk all the way through ensuring every time one of you feet is on the ground or you can just swim which is
more risky (no contact with ground) but makes you move a lot faster.
TDD is like walking.
He is referencing to Dan North session from NDC 2012.
The answer is YES! And for the following reason.
Picture yourself the following scenario. You and your project team have created a great application and decide to put it in production. After a while a user comes to you saying: Hey guys I found a bug in your application can you fix it please? Of course you say yes fix the bug and the user is happy. Only after a while he comes back saying, great that you fixed the problem but now something that did work doesn't anymore can you repair it?
If you had used TDD and had made unit tests for the application the scenario wouldn't be like this. This is because you have tests made for your entire application. After solving a bug, you simply run the unit tests again to see if your "fix" din't break any other things in your application.
This answer is more aimed at the use of unit tests. The following is abbout TDD itself.
What TDD makes you as an individual do is think about what am I going to code in the following (object, class, function and so on). Also what are the edges of my code what if/else statements do I need what do I need to check for. If you are by yourself or in a project team of 20 people, this doesn't really matter. The thing with TDD is the thinking process of you not the other people in your project.
If you are doing UnitTesting its only a small step to adopt TDD. But you will benefit much more from it.
Just one example: TDD defines that you implement your tests first. This implies that you think about the goal that you want to achieve before you start to implement. This leads to better code.
TDD and Unit Testing are not alternatives to each other. In every project you should test your code, this is where you do Unit Testing and Integration and System Testing.
TDD is however, a development model. Like Waterfall and other development methods, TDD is a method too. In TDD you have some basic requirements and you write unit tests to ensure that the requirements are implemented and working. But when you are writing unit tests you realize that in order to achieve the major requirements, you need to implement more functions and classes. So unit tests in this context makes other requirements clearer.
Suppose that you need to write an application that prints the name of the computer the application is running on. First you write a unit test:
[Test]
public void ProducedMessage_IsCorrect()
{
AreEqual(BusinessLibrary.ProduceMessage(), System.Environment.MachineName);
}
and then you realize you need to implement the ProduceMessage function. You implement it as simple as it gets so that the unit test passes. You write the method like this:
public string ProduceMessage()
{
return "MyComputer";
}
Then you run the test and it passes. After that you submit your code and other members of the team gets the code. When they run the test the test fails because you hardcoded the name of your computer in the code.
So some wise member of your team changes the code to the correct form and you keep going.
It is all about choosing developers who have TDD experience. At least some of them should be experienced TDD developers I think.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 6 years ago.
Improve this question
I am interested in Behavior Driven Development (BDD)
Are there any good frameworks and/or tooling available for the .Net platform (preferably C# and ASP.Net)?
And when has BDD proved most appropriate to use in real world scenarios? (auxiliary question)
+1 for people's recommendation of SpecFlow for scenarios; never used it but heard many good things about it. I've been using plain old NUnit with a little DSL like this. MSTest would work similarly.
You can also do BDD in the unit space, which is what MSpec is designed to do. I'm personally hating MSpec, but the rest of the team here love it. They like writing examples of how the code works. I like to show why the behavior is valuable. It's a subtle distinction and if you're not worried about doing this at a unit level it won't hit you.
Other frameworks to look at include Concordion, Fitnesse.NET (please put FitSharp behind it!) and TickSpec.
In the real world, the most valuable bit of BDD by a long way is the conversations, not the automated tests. Here's a couple of quick hints and tips for making it work:
Don't write automated tests over things which are in flux. It just commits you to stuff you got wrong. Wait until the UI has settled a bit then do it.
If you don't care much about your UI, but do care about data integrity, write the scenarios over the controller / presenter layer (eg: for admin screens).
Don't start with login. Start by describing a valuable part of the application for which you might log in. Do that first (assume you only have one user). You'll get quicker feedback on the risky bits.
Seek quick feedback on the risky bits, which will usually be the bits which you've never done before. Use scenarios to have conversations around them. Write anything interesting you discover down, but forget the scenarios which are obvious - they're obvious! Don't worry about automating them to start with. Having conversations is more important than writing down conversations is more important than automating conversations.
Good luck! If you want to know more about BDD, I put together a page of relevant links here.
On googling I found Behavior Driven Development (BDD) with SpecFlow and ASP.NET MVC. You might find it useful, take a look. Also go through Behavior-Driven Development with SpecFlow and WatiN
A nice presentation on Pros and Cons of BDD
A channel 9 video Behavior-Driven Development in the Real World
and last but not least an InfoQ article Behavior Driven Development In .NET
LightBDD is an open source framework allowing to write BDD tests that are easy to read but also easy to maintain and extend when project grows larger.
The main features that it offers are:
easy to read scenarios,
easy maintenance of tests,
integration with well known testing frameworks (NUnit / MbUnit / MsTest / xUnit),
scenario steps execution tracking and execution time measurement,
test execution summary report generation in HTML (an example report), XML and plain text format.
It bases on tests that are written purely in code, which means native support for refactoring, code analysis, test running and all other features that Visual Studio / Intellisense / Resharper offers.
An example test written in this framework looks as follows:
[TestFixture]
[FeatureDescription(
#"In order to access personal data
As an user
I want to login into system")] //feature description
[Label("Story-1")]
public partial class Login_feature //feature name
{
[Test]
[Label("Ticket-1")]
public void Successful_login() //scenario name
{
Runner.RunScenario(
Given_user_is_about_to_login, //steps
Given_user_entered_valid_login,
Given_user_entered_valid_password,
When_user_clicked_login_button,
Then_login_is_successful,
Then_welcome_message_is_returned_containing_user_name);
}
}
More information about framework could be found on project wiki page and project main page.
Also MSpec is a good framework.
I use it in the Microsoft stack you mention (C#, ASP.Net and MVC) and I like his syntax.
BDD helps you thinking in business/feature oriented way not just in a code way.
So you are most focused on business value.
It also helps in user acceptance test to create a trust between you and customer.
There is a great tool, called SpecFlow.
SpecFlow is inspired by Cucumber — the well known BDD framework for Ruby on Rails. And has a huge amount of advantages.
You should definitely check it out.
One interesting BDD frameworks is Concordion.NET. It is an open source BDD framework for the Microsoft stack that uses NUnit to execute the Concordion.NET tests: https://github.com/concordion/concordion-net
As Concordion specifications are written in simple HTML, it provides a good basis for a living documentation system. You can use a what-you-see-is-what-you-get (WYSIWYG) editor like BlueGriffon to describe your intended behavior of your software in simple HTML documents and instrument them to verify your system under test.
According to the excellent classification of BDD tools, Concordion.NET focuses on business readable input (and reaches business readable output as well). It moves even beyond BDD and supports ATDD: http://assertselenium.com/2012/11/05/difference-between-tdd-bdd-atdd/
Spec4Net (https://bitbucket.org/fthomsen/spec4net/) is a nice framework too. We use it extensively at work. The learning curve is almost non-existing and the natural flow seems intuitive.
We have a project that is starting to get large, and we need to start applying Unit Tests as we start to refactor. What is the best way to apply unit tests to a project that already exists? I'm (somewhat) used to doing it from the ground up, where I write the tests in conjunction with the first lines of code onward. I'm not sure how to start when the functionality is already in place. Should I just start writing test for each method from the repository up? Or should I start from the Controllers down?
update:
to clarify on the size of the project.. I'm not really sure how to describe this other than to say there's 8 Controllers and about 167 files that have a .cs extension, all done over about 7 developer months..
As you seem to be aware, retrofitting testing into an existing project is not easy. Your method of writing tests as you go is the better way. Your problem is one of both process and technology- tests must be required by everyone or no one will use them.
The recommendation I've heard and agree with is that you should not attempt to wrap tests around an existing codebase all at once. You'll never finish. Start by working testing into your bugfix process- every fixed bug gets a test. This will start to work testing into your existing code over time. New code must always have tests, of course. Eventually, you'll get the coverage up to a reasonable percentage, but it will take time.
One good book I've had recommended to me is Working Effectively With Legacy Code by Michael C. Feathers. The title doesn't really demonstrate it, but working testing into an existing codebase is a major subject of the book.
There are lots of approaches to fitting tests around an existing codebase. Unit tests are not necessarily the most productive way to start. If you have a large amount of code written then you might want to think about functional and integration tests before you work down to the level of unit tests. Those higher level tests will help give you broad assurance that your product continues to work while you make changes to improve the structure and retrofit unit tests.
One of the practices that non-test-first organizations use that I recommend highly in your situation is this: Have someone other than the author of the original code section write the unit tests for that section. This gets you some level of cross-training and sanity checking, and it also helps ensure that you don't preserve assumptions which will do damage to your code overall.
Other than that, I'll second the recommendation for Michael Feathers' book.
For a legacy project with a decently sized code base, unit testing everything may not be a justifiable effort spend due to budgetary constraints etc. Based on my reading on this subject, I would suggest:
Every bug which has been leaked to QA, Release or Production environment is a candidate for writing unit test case(s) along with fixing the bug.
Use source control to find out which sections/files of your code base are changing more frequently than others. Bring those sections/files under unit test coverage.
New story development should have meaningful unit test case written against them.
Keep monitoring the unit test coverage to observe any downward trend in particular area of the code base. This area needs you to zoom-in and review if unit test coverage is loosing its effectiveness or not.
P.S.: I have added Michael Feathers book to my reading list, thanks for suggesting it.
We have a large body of legacy code, several portions of which are scheduled for refactoring or replacement. We wish to optimise parts that currently impact on the user-experience, facilitate reuse in a new product being planned, and hopefully improve maintainability too.
We have quite good/comprehensive functional tests for an existing product. These are a mixture of automated and manually-driven GUI tests, but they can take a developer more than half a day to run fully. The "low-level domain logic" has a good suite of unit tests (NUnit) with good coverage. Unfortunately, the remainder of the code has no unit tests (or, at least, no worthy unit tests).
What I'd like to find is a tool that automatically generates unit tests for specific methods/classes and maybe specific interfaces based on their use and behaviour in the functional tests. These unit tests would be invaluable for refactoring, and would also be run as part of our C.I. system to detect regressions much earlier than is currently happening (and to localise regressions much better than "button X doesn't work.").
Do any such tools exist? Do you have any recommendations for me?
I've come across Parasoft .TEST, which looks like it might do want I want. Do you have any comments on that, with respect to my situation?
I don't think something that just generates test code from a static analysis, ala NStub, is useful here. I suppose it is actually the generation of representative test data that is really important.
Please ignore the merits, or lack of, of automated test generation - it is not something I'd usually advocate. (Not least because you get tests that pass for broken code!)
Try Pex:
Right from the Visual Studio code editor, Pex finds interesting input-output values of your methods, which you can save as a small test suite with high code coverage. Pex performs a systematic analysis, hunting for boundary conditions, exceptions and assertion failures, which you can debug right away. Pex enables Parameterized Unit Testing, an extension of Unit Testing that reduces test maintenance costs.
Well, you could look at PEX - but I believe that invents its own data (it doesn't watch your existing tests, AFAIK).
I am writing a simple web app using Linq to Sql as my datalayer as I like Linq2Sql very much. I have been reading a bit about DDD and TDD lately and wanted to give it a shot.
First and foremost it strikes me that Linq2Sql and DDD don't go along too great. My other problem is finding tests, I actually find it very hard to define good tests so I wanted to ask, What is your best techniques for discovering good test cases.
Test Case discovery is more of an art than a science. However simple guidelines include:
Code that you know to be frail / weak / likely to break
Follow the user scenario (what your user will be doing) and see how it will touch your code (often this means Debugging it, other times profiling, and other times it simply means thinking about the scenario) - whatever points in your code get touched by the user, those are the highest priority to write tests against.
During your own development the tests you ran that resulted in bugs you found - write tests to avoid the code regressing again with the same behavior.
There are several books on how to write test cases out there, but unless you are working in a large organization that requires documented test cases, your best bet is to think of all the parts in your code that you don't like (that aren't "pure") and make sure you can test those modules thoroughly.
Well, going by the standard interpretation of TDD is that the tests drive your development. So, in essence you start with the test. It will fail, and you will write code until that test passes. So it's kind of driven by your requirements, however you go about gathering those. You decide what your app/feature needs to do, write the test, then code until it passes. Of course, there are many other techniques but this is just a brief statement about what is typically thought in the TDD world.
Think. Read the code. Question yourself: e.g. can this pointer never be NULL here ? What happens if this method is called before the initialization ?
Don't make assumptions such as "this file will always be there". Test.
Think about edge cases, boundaries, negative values, overflows ...
Bug are often grouped by cluster. Look around when you find one. Also look for the same kind of bug in other locations.
Set your mind to the actual goal of testing: Finding bugs.
Be creative at imagining what could make your program fail.
Your tests must find bugs, not confirm that your program is OK.
I regularly write tests for third-party APIs. That way, when the API updates, I know whether I'm going to break or not.
I think this is a useful technique:
Using contracts and boolean queries to improve quality of automatic test generation
Reference: Lisa (Ling) Liu, Bertrand Meyer and
Bernd Schoeller, Using contracts and boolean queries to improve the
quality of automatic test generation, in proceedings of TAP: Tests
And Proofs, ETH Zurich, 5-6 February 2007, eds. Yuri Gurevich and
Bertrand Meyer, Lecture Notes in Computer Science, Springer-
Verlag, 2007.