Checking software requirements - tdd

As part of a homework assignment, I have to check an SRS (Software Requirement Specification) document for mistakes. One of the chapters look like this:
4 - Verification
The current specification of the system will be
inspected by an external team of experts.
Unit tests and integration tests must be used to verify the system.
The system will be developed partly by TDD method.
My problem is the last sentence. Does that even make sense? To develop something partly by TDD? I have to give a reason for everything, and I don't know how to explain this one: is it plain nonsense, or it's sensible, but not a full definition (what part is TDD? what happens to the other parts?).
Thanks in advance,
Gabe

TDD (Test Driven Development) is a development process such that developers write tests that their future code will have to pass. It provides guidelines that the developer has to follow to pass the tests.
Back to the question, it sounds like to me that there is a current system in place in which experts are going to inspect. Then afterwards for future development (in which this RS was written for) they are going to use TDD; unit tests and integration tests are part of TDD. So I think this makes sense but I would spend a little time reading about TDD.

Related

Does Behavior Driven Development just Acceptance testing Software?

I want to know that,does BDD just work in acceptance test level? If not, does it work in unit test level as well? Does BDD have any suggestion For Unit tests?
thank you
BDD is just a way of defining the specifications for an area of functionality. The idea is to bridge the gap between technical and non-technical people by using human readable syntax of some kind and to use specific examples to define the desired behaviour rather than talking in the abstract. As such it is a tool to help people work together and define the business' requirements for the new functionality. This is the primary point of BDD. Not testing.
The definitions that come out of BDD are however, useful for acceptance testing as they define the expected behaviour that was agreed upon. As such many great tools like cucumber are available to facilitate automation of these scenarios to cut down on your testing time.
With regard to using BDD for something like unit tests, the idea of using BDD and non-technical descriptions is to help involve non-technical people. If there are no non technical people involved in the creation of your unit tests (which I guess is the most likely case) then why bother with it? Technical people can read unit tests that are properly written, just fine. The unit tests that you're writing will come out of the functionality that is described by your BDD scenarios anyway.
However, if there is some technical detail of what you're working on that you're having trouble describing, and your team are comfortable working in a BDD way then definitely give the non-technical language and specific examples approach a go. I just wouldn't bother using the the human readable language version of the example in your unit test.
Edit: After reading xmojmr 's comment about your question, I can absolutely see the benefit of using BDD tools and syntax to make your unit tests more readable/easier to plan out, but I think this is quite different from BDD in general, which is more about bridging a communication gap.
BDD actually started at the class level. The first incarnation of JBehave was a replacement for JUnit that avoided the word "test". It was only later that the system-level stuff came along after Dan North explained mock objects to Chris Matts, an analyst at the time who was learning how to code.
These days, even unit testing frameworks don't insist that you start your test methods with the word "test", and the frameworks for the dynamic languages are pretty much derived from RSpec, which was a port of JBehave's early functionality to Ruby anyway.
So, yes, it's perfectly possible to do BDD at that level.
Of course, alannichols is right in saying that the audience is different, being non-technical.
So why would you want to do BDD?
As Dan says in that first link, it turns out that talking about behaviour is more useful than talking about tests. In BDD, we just avoid the word test. We prefer talking about examples and how things should behave rather than pass or fail.
By having conversations around the desired behaviour of a system or class, and providing examples of that behaviour, you can explore it more easily than when you're talking about testing.
However, because it's a non-technical audience, I find it's enough to put the "given, when, then" in comments. You can see an example here. You don't need an explicit BDD tool.
If you can't find another dev to talk about the behaviour with, I suggest you find a rubber duck.

Does BDD pay off?

I a bit familiar with rspec [Ruby] and specs [Scala]. Yesturday I passed a tutor for Cucumber. What I disliked about Cucumber is that additionally to describing scenarios (like you would do with spec- or xUnit-style testing) you have to implement extra layer of indirection: translating scenario steps into ruby expressions. For me creating unnecessary (?) extra layers of indirection feels like "heavy-weight" J2EE-way, not like "light-weight" ruby way. Is understandability by "domain experts" the only advantage of Cucumber? Or is there some non-obvious (technical?) advantages for developer/tester as well?
BDD, from a practical standpoint, is highly synonymous with TDD. Rspec is a BDD test framework, as well as Cucumber.
That stakeholders can read and understand Cucumber acceptance specifications is certainly a key advantage, but this fact alone really doesn't get at the real benefit of Cucumber. Your features and scenarios ought to grow somewhat in specificity as the work being done for them moves through the value stream of your team's development cycle.
Some teams may have an analyst scoping out work at the beginning of the cycle. Sometimes this analyst writes gherkin acceptance specifications, but whoever writes the first draft, you would expect them to be fairly coarse grained. They may not cover every un-happy path.
As the developers take up the work, they often discover edge cases and missing scenarios. At this point they can touch base with the analyst, and the results of such conversations should be written into the cucumber features.
In my experience the testers have cultivated an even more critical eye, and thus it is not uncommon to see them add even more scenarios and features. The testers may also uncover defects, which should be added to the cukes to protect us from regression.
The point is that, in addition to providing executable documentation for our code, Cucumber also provides a repository for the state of the team's conversations vis a vis the features being developed.
There is certainly extra overhead to all of this. However, it's worth considering how much overhead is already in your team's process, which Cucumber might serve to streamline. I find that Cucumber helps reduce the amount of thrash that happens in communication about features both within and outside of the team room.
I should also mention that cucumber is intended as full-stack acceptance testing, and therefore should be less fine-grained, relative to your unit tests. And cucumber is not a good substitute for unit and integration tests. I also would never recommend using cucumber to verify aesthetic aspects of your app's UI. Just use it to validate the actions which a user might take when using your app.
Cucumber is designed to help engage business stakeholders in refining developers' and testers' understanding of the system by collaborating to create scenarios that everyone can understand.
The act of engaging business stakeholders pays off because everyone gets a better understanding, they start sharing the same language and carrying that language into the code (see Domain Driven Design's "Ubiquitous Language"), which can lead to better estimates, appreciation of scope, conversations around options for achieving the same goal, etc. etc.
There are certainly other ways of achieving the goals. For instance, on our C# project we talk through the scenarios, write them on a wiki then implement them using a little custom Domain Specific Language rather like this one. The same thing could be done in Ruby.
BDD is the process of learning the places where we thought we knew what we were doing, but it turned out we were wrong - the discovery of ignorance. With Feature Injection and unit-level examples, this happens at multiple levels of granularity, all the way up to the project vision itself. It tends to pay back for itself, but you don't need a BDD framework to do BDD.
The conversations in BDD are the important bits, not the tool you use to capture them (I helped write JBehave and still believe this is true). Automating regression tests is also important to cut down the manual effort which rises as the codebase grows, and Cucumber, DSLs and other BDD tools give you this as a very nice by-product which also help you trace, and drive out, the shared understanding.
Edit: I should mention that the reuse of steps is also important, but it doesn't make much difference whether you use a BDD framework or a DSL for that. It does make the difference between a DSL and just procedurally mimicking every user interaction.
It depends what you want to achieve.
Cucumber adds overhead, can be tricky to get used to, takes time to master.
If you want your domain experts to be able to read your tests, you should definitely give it a try.
On the other hand, if developers are the only people reading your tests, you can probably stick to rspec/unit-test/etc. and write your integration tests in those frameworks. However you might achieve more readable high level documentation by using cucumber.
See for example rspec 2 core features' descriptions in cucumber.

When should I opt for test driven development?

My question is same as the title. I have not done Test driven development yet,I have performed unit testing and I am aware of testing in general but I hear it is much advantageous to follow TDD?. So should I opt for it everytime or are there some preconditions... i just need to know some basic or important requirements when i should opt for TDD. Sorry if this question is too trivial.
I would say whenever you are coding for a project. By this I mean where you are hoping to produce code that will be used by people. This is basically all code apart from research where you are learning and discovering new techniques.
Even if you think the project is just a small one often things spiral up out of control without care. You wil be glad for the tests when you find yourself having to refactor a big sprawl of code.
Also note that tdd isn't just about testing. It is a methodology of development that encourages you to create clean and solid designs.
As you are starting out tdd everything. Once you have more experience then perhaps you can back off and determine when to not tdd.
IMHO if you are not comfortable with TDD, trying to apply it in projects where you will need to interact/use legacy code it's much more complex than applying it in a project from scratch. In fact, there is a whole book about this.
HTH
My advice would be to use unit testing as often as possible.
Caveat: In my experience TDD works best when working with technologies you already have some experience with. It's often hard to write test assertions if you do not know exactly what the desired result looks like (For example, try writing the test for an ASP.NET MVC action method if you never wrote an action method in your entire life). In those cases you're probably better off writing unit tests after implementing the code.
If I am developing something without a user interface, I always use TDD these days. After all, you have to test the software. You can either do the extra work and do TDD, or you can do the extra work and cludge together a user client just for testing. The former tests more completely and in a more repeatable fashion.
Doing TDD against user interface code, on the other hand, hasn't really delivered much value for me. For various business reasons I'm restricted to Visual Studio out of the box for my work, and "recording" tests with VS is a huge time sink, especially when you have to re-record them if you change the UI. I do TDD for the business logic behind the UI, but not the UI itself.

How do I start unit testing?

I know that unit testing is desirable, and I am interested in doing unit testing. The only problem is I have no idea how, or even where to start really. So my question is: How do I learn about and start unit testing? Specifically I frequently write Java code in NetBeans and C# code in Visual Studio and am interested in what tools to use and how to get my feet wet. Can anyone offer any advice for an absolute unit testing n00b?
I know that there are a lot of somewhat similar questions out there but I am less interested in why and more interested in how.
Try to read on StackOverflow, tag unit-testing :)
Is Unit Testing worth the effort?
How to make junior programmers write tests?
What is unit testing?
How do you know what to test when writing unit tests?
Another entry point would be the tags junit and nunit
There are lots of question dealing this.
If you're searching books about Unit Testing, try this thread:
Good C# Unit testing book. There the famous Kent Beck book is mentioned, "Test Driven Development By Example".
It's worth reading!
Good luck!
This Tutorial for writing JUnit tests in NetBeans should give you an idea how unit testing is done technically. NUnit for C# works pretty much the same.
For an advanced view of how to integrate unit testing into you daily development, the standard reference is Kent Beck's "Test Driven Development By Example". Here's a broad overview.
If you really want to understand unit testing (and get hooked), try it out, it should only take a few hours!
First, I recommend downloading a unit testing framework, such as NUnit (if you want to start with .NET / C#).
Most of these frameworks have online documentation that provides a brief introduction, like the NUnit Quick Start. Read that documentation, then choose a fairly simple, self-contained class for which you are responsible. If you can, try to choose a class that:
Has few or no dependencies on other classes - at least not on complex classes.
Has some behavior: a simple container with a bunch of properties won't really show you much about unit testing.
Try writing some tests to get good coverage on that class, then compile and run the tests.
Unit testing is simple to learn and hard to master (apologies for the cliché, but it is appropriate here), so once you've done this, start reading around: for example, guerda has provided several excellent links in another answer to this question.
Start small.
Unit testing (and automated testing in general) isn't a silver bullet, doesn't always apply to every situation and can be a bit of a culture shock. That said, if you're writing software that you're selling or that your company relies on, I highly recommend adopting it. You'd be surprised how many professional development shops don't.
First, get comfortable the mechanics of creating and running unit tests with your development tools.
Then, start with a new (preferably small, but not necessarily trivial) class or method that you want to test. Writing tests for existing code has its own challenges, which is why you should start with either something brand new or something that you are going to rewrite.
You should notice that making this class or method testable (and therefore reusable) has an impact on how you write the code. You should also find that thinking about how to test the code up front forces you to think about and refine the design now instead of some time down the road "when there's more time". Things as simple as "What should be returned if a bad parameter is passed in?". You should also feel a certain amount of confidence that the code behaves exactly the way you expect it to.
If you see a benefit from this exercise, then build on it and start applying it to other parts of your code. Over time, you'll have confidence in more and more of your software as it becomes more provably correct.
The hands on approach helped get my head around the subject better than a lot of the reading material and helped fill in the gaps of things I just didn't understand. Especially where TDD was concerned. It was counter-intuitive until I actually tried it.
Find-a-bug-write-a-test
The next time you find a bug in your code base, before fixing it, write a test. The test should fail. Then, fix the bug. The test should pass.
If the test doesn't pass, there's either a bug in your test, or a bug in your fix.
A person will never find that bug in your code again. The unit tests will find it (and faster than a person can).
This is definitely a small start, but it gets you into testing. Once you've got the hang of it, you'll probably start writing more tests, and eventually get a knack for how code will fail and which tests you need (for example: a test for every business rule).
Later in your progression you setup a continuous integration server, which makes sure your codebase is always solid.
A good start is to buy a good book where you can read about unit-testing.
I have a tips on a book called "Software testing with visual studio team system 2008" and it takes you trough the basics stuff and background to more higher levels of unit-testing and practises.
Check out The Art of Unit Testing by Roy Osherove, it's a good book for beginners since it starts at the very beginning.
I would recommend reading Michael Feathers' "Working Effectively with Legacy Code". Old code often ends up being code that's hard to Unit Test. Feathers' book is a great guide in how to refactor your code to the point that unit tests are a snap to write.
Not exactly an answer to the question you asked, but might be a missing step between where you are, and where you need to be to implement some of the answers others have given.

I know I may not write production code until I have written a failing unit test, so can I tell my manager I cannot write UIs? [closed]

Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 10 years ago.
Improve this question
I've been using TDD for server-side development. I'm not really sure if the benefits of having all of my production code surrounded by unit tests outweigh the disadvantage of spending 4x more time than needed on refactoring.
But when I'm developing UI code, I simply cannot apply TDD. To all fundamentalists out there, the first law of TDD states that "you may not write production code until you have written a failing unit test". But how can this be if you are developing UIs?
(One can use acceptance test frameworks like Selenium, but that doesn't count, because you don't interact directly with the source code.)
So, can I tell my manager that because of the new >90% code coverage policy I cannot write user interface code?
If you find that writing TDD causes you to spend 4x more time on refactoring, you need to be writing better, more isolated tests, and really let the tests drive the design, as intended. You are also not counting the time you spend in the debugger when you refactor without tests, not to mention how much time everyone else spends on bugs you introduce when you refactor.
Anyway, here is some good advice about what TDD means for UI development. How much that will translate into code coverage depends heavily on the UI framework.
Definitely don't tell your manager you can't do it, he may just replace you with someone who can.
First off, even Robert Martin has testing challenges with UIs.
When TDDing a UI, you write "behavioral contracts" that get as close to the action as possible. Ideally that means unit tests. But some UI frameworks make that inordinately difficult, requiring that you step back and use integration or "acceptance" tests to capture how you expect the UI to behave.
Does it not count if you can't use unit tests? That depends on which rules you're using to keep score. The "only unit tests count" rule is a good one for beginners to try to live with, in the same vein as "don't split infinitives" or "avoid the passive voice". Eventually, you learn where the boundaries of that rule are. In one podcast, Kent Beck talks about using combinations of unit and integration tests, as appropriate (adding, if I recall correctly, that it doesn't bother him).
And if TDD is your goal, you can most certainly write Selenium tests first, though that can be a slow way to proceed. I've worked on several projects that have used Selenium RC to great effect (and great pain, because the tests run so slowly).
Whatever your framework, you can Google around for TDD tips from people who've fought the same battles.
TDD is about testing methods in isolation. If you want to test your UI you are doing integration tests and not unit tests. So if you carefully separate the concerns in your application you will be able to successfully apply TDD to ANY kind of project.
That policy sounds a little artificial, but I would agree with the answer that UIs require functional test cases, not unit test. I disagree however with the point about which comes first. I've worked in an environment where the UI functional tests had to be written before the UI was developed and found it to work extremely well. Of course, this assumes that you do some design work up front too. As long as the test case author and the developer agree on the design it's possible for someone to write the test cases before you start coding; then your code has to make all the test cases pass. Same basic principle but it doesn't follow the law to the letter.
Unit tests are inappropriate for UI code. Functional tests are used to test the UI, but you cannot feasibly write those first. You should check with your manager to see if the >90% code coverage policy covers UI code as well. If it does, he should probably seriously rethink that move.
Separate the business logic from the UI and ensure that the UI code takes less than 10% of the total? Separation of concerns is the main goal of TDD, so that's actually a good thing.
As far as 90% coverage goes ... well, best course is to review extant literature (I'd focus on Kent Beck and Bob Martin), and I think you'll find support for not following a mindless coverage percentage (in fact, I think Uncle Bob wrote a blog post on this recently).
A having a >90% code coverage is dumb because a smart dev can get 100% coverage in one test. ;)
If you are using WPF, you can test your UI code if you use the MVVM pattern. By test your UI code, i mean you can test the ModleView but there is nothing that I know that can test XAML.
Read Phlip's book

Resources