<p>I always have mixed feelings about TDD. If TDD is to emphasize the important to writing test code, yes by all means. But if TDD is to make you to write test code <strong>before</strong> implementation, <strong>NO</strong> I am totally against it.</p>
<p>There is a lot of exploratory &amp; discovery in the development process and only when you actually implement something (through experiment and iteration) you will know what good tests should look like.  To exaggerate my point a little bit, if my Function X should take a name and output a greeting with that name, then writing the test code beforehand for my Function X sounds pretty sweet. Anything more complicated than that will make writing test code beforehand quite pointless. You may also refer to <a href="https://hackernoon.com/test-driven-development-is-fundamentally-wrong-hor3z4d" rel="nofollow noreferrer">Test-Driven Development is Fundamentally Wrong</a>. There are only some rare occasions that I find writing test first may make sense, one of them is to implement a homegrown bitarray (one of my assignments to the student) because even I have not figured out how to implement it I know what bitarray should behave so I can write test code first.</p>
<p>But this is a site for teaching and my answer is not to argue with others. Part of reason I answered it is I saw your words &quot;<em>Even though the teachers <strong>invariably encourage it</strong> and present it as a useful strategy</em>&quot;.</p>
<p>As a teacher I will first emphasize the importance of writing test, then introduce TDD. But I emphasize that I am personally against writing test before implementation, but there are also many people embrace that idea, you probably need to try it yourself to figure out whether that is for you or not.</p>
<p>One of teacher's job to make students's eye open. So I may even go further (not for high school students) to mention that even we all agree writing unit test is a must but there is a crazy company called Tictok that they don't really write unit test and they still makes a huge success, check here for the detailed &quot;<a href="https://www.youtube.com/watch?v=RNUrZFkHXlo" rel="nofollow noreferrer">5 crazy things about working for Tiktok</a>&quot;(youtube video) or here, <a href="https://twitter.com/LucasOuYang/status/1493408428626100226" rel="nofollow noreferrer">the text version</a> . The point here is that there are many ways to do things and your job as a student to experience as much as possible.</p>
<p>--- update ---</p>
<p>After reading &quot;<a href="https://neugierig.org/software/blog/2022/12/chrome.html" rel="nofollow noreferrer">Chrome, 10 years later</a>&quot; I got another surprise, just like when I watched that Tiktok video. It makes me think again is UT really that important?</p>
<blockquote>
<p>Working with Apple.</p>
<p>In retrospect I enjoyed this a lot, for two reasons. One is that
getting code review from experienced engineers is one of the best ways
to grow as a programmer, and the Apple engineers came from a totally
foreign engineering culture — no unit tests! no comments! — that also
was clearly producing a high-quality product.</p>
</blockquote>

CC BY-SA 4.0
2022-10-13T18:42:45.817Z
The problem with post testing for students is that once they write the code they are too likely to write tests that test exactly that code, not whether it meets the spec. It is too easy to miss boundary conditions and such, for example.
Buffy
CC BY-SA 4.0
2022-10-13T18:45:01.203Z
And for professionals, it is too easy to just ignore the testing in light of pressing schedules. No time to get it right, but plenty of time (needed) to fix it later.
Buffy
CC BY-SA 4.0
2022-10-14T02:30:20.667Z
That is one of points in [Test-Driven Development is Fundamentally Wrong](https://hackernoon.com/test-driven-development-is-fundamentally-wrong-hor3z4d) "Because the same blind spots that I had in design will appear in my tests".  "No time to get it right, but plenty of time (needed) to fix it later." is indeed a problem I hit many times and I don't have a good way to fix that too.
Qiulang 邱朗
CC BY-SA 4.0
2023-05-25T20:13:08.610Z
*"But if TDD is to make you to write test code before implementation,"* **--** TDD is **not** writing tests before the code.
Timothy Truckle
CC BY-SA 4.0
2023-05-26T01:26:40.070Z
@TimothyTruckle well, many say it is.
Qiulang 邱朗
CC BY-SA 4.0
2023-05-26T17:22:56.990Z
@Qiulang邱朗 those are wrong.
Timothy Truckle
CC BY-SA 4.0
2022-10-13T08:28:56.503Z
2023-02-20T10:07:27.813Z
2023-02-20T10:07:27.813Z
Qiulang 邱朗
<p>The first mistake teachers usually make is not changing the point of view:</p>

<p>Unittests should be recognizes as "verifies <em>what my code does</em>" and <strong>not</strong> as  "verifies my code <em>is right</em>".</p>

<p>Unittests are <em>executable specification</em>. With your set of unittests you can <em>prove</em> which parts of the requirements you really implemented.</p>

<p>One way to teach that to students could be like this:</p>

<ul>
<li>Split you students in teams of two.</li>
<li>give each team a separate task to implement. This task should be too big to be completed.</li>
<li>force half of the teams to do TDD, let the others go without tests.</li>
<li>at the last day let the teams change their results so  that TDD teams get the task of another TDD team and the "no tests" teams also change their results.</li>
<li>let the teams work on the inherited project for half a day.</li>
<li>after haft of the day do the same change as in the morning but this time give the TDD teams a "no tests" project and vice versa. </li>
<li>Let them start with the same project state as in the morning and complete this newly inherited project. </li>
</ul>

<p>The lessons leaned will be:</p>

<ul>
<li><p>without the unittests you first have to learn what the code already does by <em>manually</em> testing it. This is some effort even for small projects. </p></li>
<li><p>with unittest in contrast you can simply <em>read</em> what the code already does and start implementing new behavior right away.</p></li>
</ul>

CC BY-SA 3.0
2017-06-22T22:28:43.960Z
Welcome to CSeducators Stack Exchange! `unittest`  it Python specific, and if the class if based on Python this could be a good project. Could the same project concept be developed to apply to any language?
Gypsy Spellweaver
CC BY-SA 3.0
2017-06-23T12:18:39.503Z
@GypsySpellweaver I don't see why this should be restricted to any language.
Timothy Truckle
CC BY-SA 4.0
2023-03-02T14:27:33.443Z
This is a great idea, but as some of the other it doesn't really works when you don't have days and days...
YCN-
CC BY-SA 4.0
2023-03-05T13:09:05.070Z
@YCN- You are right, but TDD isn't something you can learn in two hours. TDD is a **skill** that needs to be developed and trained.
Timothy Truckle
CC BY-SA 4.0
2023-03-06T15:28:29.140Z
@TimothyTruckle definitively, I've managed to find an alternative, I'm showing them the technique live in class, and asking them afterward to do that on exercises that goes from very dummy stuff around string and then goes up to database insertion, rest api testing, sudoku grid verifying and that kind of stuff. And after that we get into the project where I ask them to use tdd and develop a simple api, for instance this year we made a very stupid copycat of pastebin.
YCN-
CC BY-SA 3.0
2017-06-22T21:16:18.947Z
2017-06-22T21:16:18.947Z
Timothy Truckle
<p>I'd like to add two notes. First is that if <strong>you</strong> write both the unit tests and the code, then all they test is that the code does what <strong>you</strong> think it is supposed to do, not what it is <em>actually</em> supposed to do. That is why Acceptance Tests are also used in agile development to test that the code does what the client/customer thinks it is supposed to do. With an imperfect understanding of requirements (or an incomplete test suite) you can pass all the tests and still not have a valid program. Also, if you write the tests <em>after</em> the code, then all they test is that the code does what the code does. That is a waste of time, of course, except, perhaps, for regression. </p>

<p>Second, in the context of a course, if you are lucky enough to be able to project a computer screen for all to see then you can spend part of a class period developing a small application (100 or so lines) in front of the class, perhaps with a student "navigator" showing how TDD actually works. Bit of test, bit of code, repeat. </p>

<p>You can also expect that the number of lines of code in tests exceeds the number of lines in the application itself. That is normal. But if you use an adequate programming environment it isn't a burden. Especially since something like Eclipse will fill in the application method skeletons from what it finds in the tests (assuming JUnit, at least). Think of the test framework as your low level design space, where you design the public interface of  your classes. </p>

CC BY-SA 3.0
2017-06-25T17:45:25.967Z
2017-06-25T21:22:51.510Z
2017-06-25T21:22:51.510Z
Buffy
<p>Any technique of reasonable complexity requires fluency and experience. People who use TDD/BDD are using it as one of the many tools. Starting a new project with these tools enabled should take a competent professional very little time. Minutes for small projects like utility libraries. So the idea that it takes &quot;more time&quot; is like arguing that riding a bike takes too long vs walking - if you don't know how to ride a bike efficiently and are just learning and are wobbly and falling a lot and don't feel safe. Same with TDD/BDD. For a novice it's just as big of a deal as learning to ride a bike. A year later they won't even remember why it was supposedly a big deal. It's just something you do.</p>
<p>Many programming environments make testing almost zero-effort. Say python doctests. Most Python IDEs let you run those tests from a keyboard shortcut, or a menu/toolbar control. Setup is minimal.</p>
<p>Tests also highlight how hard it may be to write bug-free software. Even &quot;simple&quot; library code may have serious bugs lurking within. If you don't test well, you'll only find them when things don't work or work flakily.</p>

CC BY-SA 4.0
2023-05-29T20:15:16.307Z
2023-05-29T20:15:16.307Z
Kuba hasn't forgotten Monica
<p>I think students might fail to appreciate the benefits of TDD if they are working primarily alone.  They probably just view it as an impediment to doing the "fun stuff", up-front grunt work they have to do before they can start coding.  </p>

<p>Even in the real world many developers fail to appreciate the benefits of thinking about testing up front until they've been through a few projects and see the chaos that can ensue when insufficiently tested code gets deployed to upper environments and/or production.</p>

<p>In the full software lifecycle, time will be spent identifying bugs and fixing them.  If you employ TDD and write test-driven code, you spend the time up front.  If instead you just start hacking away, don't test your code, and throw it over to the testing group, time will still be spent finding and fixing bugs.  It might not be spent by you but someone, somewhere will hopefully discover your bugs through testing, filing bugs, and fixing bugs.  But it's usually more time effective to think about it up front.  So while spending time doing TDD may seem annoying, it usually leads to overall time savings from the perspective of the entire project.</p>

<p>TDD in my opinion addresses two challenges that are present on almost every software project:</p>

<p>1) It's hard to collect requirements, document them, and turn them into test cases with a sufficient amount of detail that the software can be tested against actual requirements.  While it may sound simple, many requirements are identified through conversations, meetings, industry research, ideas, etc. In a team environment, not everyone is aware of every requirement.  And usually business people don't make good developers, developers don't make good testers, and testers don't make good business people, but all 3 groups have to work together.  And nobody wants to write a super long and comprehensive requirements document and try to keep it up to date, and documentation tends to become obsolete immediately.  Test driven development tries to address this by making every developer and team member part of the solution.</p>

<p>2) This last point is probably the most important point, many developers prefer only to do the "fun stuff" which is the coding, and have a tendency to assume that things like testing, accuracy, performance, integration, etc. are "someone else's problem".  They can develop a mentality of writing code, doing limited testing, and then checking it in, assuming that someone else will somehow complete it.  Some people say that this is the difference between being "done" and "done done".  Software needs to be "done done" before it can work correctly but many developers only get it "done".  TDD serves to address this problem by introducing a different mindset to the team, to make every developer aware that their code must be tested, and requires them to understand the context within which their code was developed and participate in all aspects of the software lifecycle and not just the coding.</p>

CC BY-SA 3.0
2017-06-26T14:23:45.233Z
2017-06-26T14:23:45.233Z
Uncle Long Hair
<p>When I was in industry, my boss said to me: this test driven development thing, [that we introduced recently] its real value is not that it finds bugs, or that we can re-factor without fear. The real value is that it saves us time, because it makes us think before writing the code.</p>
<h1>How to encourage its use</h1>
<p>For the project, give them code that is already weeks into development, complete with unit-tests. Then, have them add features to the code. Using TDD.</p>

CC BY-SA 4.0
2023-03-24T21:44:49.797Z
2023-03-24T21:44:49.797Z
ctrl-alt-delor
<p>The whole point of TDD is to try and reduce the number of defects in software. If your students are confident enough to think that they won't benefit from automated testing, fine — but <strong>have some tests prepared</strong> to run on their code to ensure that it's actually correct. If they fail your tests (which you need not specify in advance), then their solution is not a complete, working one, and they need to go back and figure out what went wrong.</p>

<p>I imagine you could gamify this a little bit if you wanted — <a href="https://cseducators.stackexchange.com/a/695/2">I've talked about Codewars before</a>, which uses 'hidden' unit tests to see if your solution works or not. You could do the same with your students' submissions, but you might not even need to use a framework to do that. You mentioned web services — why not just <a href="https://en.wikipedia.org/wiki/Black-box_testing" rel="noreferrer">black-box test</a> it a little to see what happens when you put in unusual results — does it fail when it should? You could even try <a href="https://en.wikipedia.org/wiki/Fuzzing" rel="noreferrer">fuzzing</a> the code to see if completely random nonsense produces the right response.</p>

<p>Essentially: <strong>make the costs in the class the same as in industry — defective code is not a valid solution to your assignments.</strong> In a job, a serious bug might cost your employer a large sum of money. You could emphasise that in your classes, and show them cases where testing has not been done, leading to huge amounts of cost.</p>

<p>If you follow TDD, you shouldn't really be spending much more time testing, unless your students replace the <em>writing tests before writing code</em> with just <em>writing code without testing</em>. Otherwise, surely the costs are very similar in terms of time if the tests get written either way? That is, of course, ignoring the productivity benefits of having tests that you can rely on while writing your code, so TDD might even be <em>quicker</em>!</p>

CC BY-SA 3.0
2017-06-22T17:19:50.463Z
2017-06-22T17:19:50.463Z
Aurora0001
<p>Give an assignment to write a function or class, and give stub code that includes tests. Initially all the tests fail. </p>

<p>Let the students know that these and other similar tests will determine score of their assignment. Encourage students to write further tests if they want to know their code is correct.</p>

CC BY-SA 3.0
2017-06-22T22:00:22.190Z
This is a nice lab idea. Welcome to CSE!
Ben I.
CC BY-SA 3.0
2017-06-23T23:31:49.843Z
Thanks! This happened to me as a student in a CS 2020 class, probably this is most effective at a specific level of complexity.
droid
CC BY-SA 4.0
2020-11-11T14:57:51.337Z
As a professional software developer, in my experience this is how a lot of real-world coding tests are given to applicants. The applicant is also encouraged to add their own tests, which often gives them a competitive advantage over applicants who don't do this.
InvalidBrainException
CC BY-SA 3.0
2017-06-22T21:50:46.183Z
2017-06-22T22:00:05.247Z
2017-06-22T22:00:05.247Z
droid
<p>The point of TDD, like many of the other answers have been saying, isn't really to test the code and find bugs, but to codify your requirements.</p>

<p>Having requirements that are codified is useful when you have a <em>lot</em> of requirements that need to be tested that all intersect each other (like in many industry projects), and when those requirements are going to change very often (which is one of the key assumptions of Agile). </p>

<p>It would be tricky to recreate the first condition in a school setting. Instead, lets focus on the second one: Throughout the project, introduce new requirements that overwrite and contradict earlier ones. </p>

<p>They might start with:</p>

<blockquote>
  <p>we need to do A, B and C.</p>
</blockquote>

<p>Once they finish that, mix things up:</p>

<blockquote>
  <p>we need to do A, C, E and F. Instead of B we need to do D instead. And
  D shouldn't change how A and C work.</p>
</blockquote>

<p>If they have good unit tests, it should be relatively easy to refactor and change their implementation. If they don't, they'll have a bad time trying to wade through their legacy code.</p>

CC BY-SA 4.0
2023-08-20T03:19:39.107Z
The first paragraph is the key. TDD is driven by requirements. You test *requirements* not code. In fact, you start with a single requirement and write one test. Then make the test pass. Add another test for another requirement and get that to pass. Repeat until all requirements are passing. And then I wish I could up-vote this answer again for *changing* the requirements — the second key point to understand!
Greg Burghardt
CC BY-SA 3.0
2017-06-23T16:58:40.650Z
2017-06-23T16:58:40.650Z
FirstLastname
<p>I believe that the reason why students tend to come out opposed to using TDD/BDD (testing) is because they've been assigned to use it when it isn't necessary. Testing a "Hello World" program is 100% a waste of time. Tests only become useful when you have a reasonably complex program. The way that you can avoid students disliking testing is by not assigning it on projects when it isn't needed.</p>

<p>A specific way in which you could do this would be by combining all the project you would assign over the year into one larger cumulative project. Eventually, as they're writing code, you can be fairly certain that they'll induce bugs or begin to find manual testing to be a pain. Once that starts happening, you can introduce automated testing to relieve that pain. That way, they'll see testing as a way to save work rather than create more of it.</p>

<p>In addition, I think the issue may be with this part:</p>

<blockquote>
  <p>TDD and BDD have high upfront setup costs in ... thinking up test cases for all the various scenarios.</p>
</blockquote>

<p>If you are spending time thinking of test scenarios, you're doing TDD wrong. You should never just take time to think of test cases. You should think about how you want each new piece of code to behave, and then testing should be a way of writing down how you want it to behave. That's just good planning, and you should be thinking about that anyways.</p>

CC BY-SA 3.0
2017-06-22T14:55:20.123Z
Wow, what kind of test could you even write for "Hello, World"? You're probably right but that's not the problem I'm describing. I'm talking about half-semester type projects done for real-world customers. Not exactly paycheck-worthy, but still full-fledged functioning web services deployed to real servers and everything solving a small need for someone in the community.
Piyush Parikh
CC BY-SA 3.0
2017-06-22T14:56:39.190Z
`assert "Hello World" == hello_world_method` I didn't realize the size of the projects being done. Would you mind editing that into the question?
thesecretmaster
CC BY-SA 3.0
2017-06-22T15:04:11.250Z
IMO TDD isn't appropriate for bootstrapping a project. It's most useful for bug fixes: create a test that replicates the bug, make sure the test fails as expected, then fix the test.
G. Ann - SonarSource Team
CC BY-SA 3.0
2017-06-22T15:07:02.503Z
I made an attempt at editing but I'm not sure what to change. The question really applies regardless of project size, setting aside the fact for the moment that TDD/BDD aren't appropriate for tiny projects. Beyond that, I think the existing "handful of weeks" covers it.
Piyush Parikh
CC BY-SA 3.0
2017-06-22T15:07:20.613Z
@G.Ann-SonarSourceTeam TDD is the process of writing failing tests, making the tests pass and repeating until the project is complete.
thesecretmaster
CC BY-SA 3.0
2017-06-22T15:59:45.823Z
Yeah, I get that @thesecretmaster.
G. Ann - SonarSource Team
CC BY-SA 3.0
2017-06-22T19:44:40.280Z
BDD doesn't required Cucumber, you can do it without a framework as long as you are willing to follow the precepts. Cucumber, SpecFlow, etc. all help you "compile" BDD into code easier. Learning to think in BDD terms helps.
AlG
CC BY-SA 3.0
2017-07-18T22:56:26.700Z
@piyush Parikh This is exactly it.  It is a waste of time if the upfront cost is more than what it would cost to just brute force the logic.  You can't appriciate a testing or development methodology until you work on a project that's too big or complex for you to fit in your head at once.
8bitwide
CC BY-SA 3.0
2017-06-22T14:47:50.090Z
2017-06-22T15:00:19.523Z
2017-06-22T15:00:19.523Z
thesecretmaster
<p>I've observed an unusual thing happen when teachers try to introduce Test-Driven Development (TDD) or Behavior-Driven Development (BDD) to their classes. Even though the teachers invariably encourage it and present it as a useful strategy, students come out of the class with mixed feelings or actively opposed to using TDD/BDD in the future.</p>

<p>The reason they give for this is time. And in a way, it makes sense. TDD and BDD have high upfront setup costs in selecting framework (e.g. JUnit or Cucumber), adding test hooks/libraries into the code (your <code>import org.junit.Test</code>s), thinking up test cases for all the various scenarios, and then of course actually writing all the tests themselves.</p>

<p>In industry, this isn't so bad, because tests are essentially infinitely reusable, so the cost of that work can be amortized over months or even years. For a class project though, the entire thing from start to finish is only going to be a handful of weeks long at best. So the students see all of the cost and only a small slice of the benefit.</p>

<p>In short, students sort of pick up on a perverse incentive to <strong>not</strong> use TDD/BDD because the benefits don't justify the cost. So, how can I convince students that those strategies really are good choices, when simply forcing them to use them and saying "it works better in the real world, I promise" isn't cutting it?</p>

<p>I've seen <a href="https://cseducators.stackexchange.com/questions/872/how-to-stress-the-importance-of-testing-code">How to stress the importance of testing code?</a>, but the answer there is just "use TDD." It's not <em>wrong</em>, but it's also not helpful for my particular question.</p>

CC BY-SA 3.0
2017-06-24T15:39:16.013Z
When I was in industry, by boss said to me: this test driven development thing, [that we introduced recently] is real value is not that it finds bugs, or that we can re-factor with out fear. The real value is that it saves us time, because it makes us think before writing the code.
ctrl-alt-delor
CC BY-SA 4.0
2022-10-04T15:37:12.700Z
Anything that forces you to think is good. Pretty sure anyway...
Scott Rowe
CC BY-SA 4.0
2022-10-13T19:38:22.207Z
Actually in correct use of TDD there shouldn't be "test hooks" in the application code. This implies that the tests can only test visible features, which are actually tests against the requirements, not the implementation.
Buffy
CC BY-SA 4.0
2022-10-26T13:17:36.870Z
You can test your hypothesis by removing setup time: given them a bootstrapped project to clone with all dependencies and configurations in place, as well a a few skeletons. (This is something that has started to pop up in the industry as well: developer portals, golden path, etc. all aim for reducing kickoff time, to the point of full automation.)
Raphael
CC BY-SA 4.0
2022-10-26T13:19:53.283Z
Also, doing TDD is not always _easy_. In the short term, it certainly _feels_ faster to just start coding. In the industry, some technical coaches run people through a series of katas to get comfortable with the technique -- _then_ they apply it to their real problem. You'll find many resources for TDD katas online; the Samman Method may also provide some inspiration.
Raphael
CC BY-SA 4.0
2023-03-02T14:23:18.573Z
@Raphael thanks for the hint I'm introducing tdd to student every year, but it's not easy to find exercises before going to the project, I didn't knew they were katas, thanks a lot!
YCN-
<curriculum-design><student-motivation><student-perceptions><unit-testing><agile-development>
How to overcome the TDD/BDD time fallacy
# How to overcome the TDD/BDD time fallacy

(Asked by: username_0 on 2017-06-22)

I've observed an unusual thing happen when teachers try to introduce Test-Driven Development (TDD) or Behavior-Driven Development (BDD) to their classes. Even though the teachers invariably encourage it and present it as a useful strategy, students come out of the class with mixed feelings or actively opposed to using TDD/BDD in the future.

The reason they give for this is time. And in a way, it makes sense. TDD and BDD have high upfront setup costs in selecting framework (e.g. JUnit or Cucumber), adding test hooks/libraries into the code (your `import org.junit.Test`s), thinking up test cases for all the various scenarios, and then of course actually writing all the tests themselves.

In industry, this isn't so bad, because tests are essentially infinitely reusable, so the cost of that work can be amortized over months or even years. For a class project though, the entire thing from start to finish is only going to be a handful of weeks long at best. So the students see all of the cost and only a small slice of the benefit.

In short, students sort of pick up on a perverse incentive to **not** use TDD/BDD because the benefits don't justify the cost. So, how can I convince students that those strategies really are good choices, when simply forcing them to use them and saying "it works better in the real world, I promise" isn't cutting it?

I've seen [How to stress the importance of testing code?](https://cseducators.stackexchange.com/questions/872/how-to-stress-the-importance-of-testing-code), but the answer there is just "use TDD." It's not *wrong*, but it's also not helpful for my particular question.

**Tags:** curriculum-design, student-motivation, student-perceptions, unit-testing, agile-development

> **Comments:**
> **username_1**: When I was in industry, by boss said to me: this test driven development thing, [that we introduced recently] is real value is not that it finds bugs, or that we can re-factor with out fear. The real value is that it saves us time, because it makes us think before writing the code.  
> **username_2**: Anything that forces you to think is good. Pretty sure anyway...  
> **username_3**: Actually in correct use of TDD there shouldn't be "test hooks" in the application code. This implies that the tests can only test visible features, which are actually tests against the requirements, not the implementation.  
> **username_4**: You can test your hypothesis by removing setup time: given them a bootstrapped project to clone with all dependencies and configurations in place, as well a a few skeletons. (This is something that has started to pop up in the industry as well: developer portals, golden path, etc. all aim for reducing kickoff time, to the point of full automation.)  
> **username_4**: Also, doing TDD is not always _easy_. In the short term, it certainly _feels_ faster to just start coding. In the industry, some technical coaches run people through a series of katas to get comfortable with the technique -- _then_ they apply it to their real problem. You'll find many resources for TDD katas online; the Samman Method may also provide some inspiration.  
> **username_5**: @username_4 thanks for the hint I'm introducing tdd to student every year, but it's not easy to find exercises before going to the project, I didn't knew they were katas, thanks a lot!  

---

## 10 answers

### Answer by username_17 on 2017-06-22. Score: 8

I believe that the reason why students tend to come out opposed to using TDD/BDD (testing) is because they've been assigned to use it when it isn't necessary. Testing a "Hello World" program is 100% a waste of time. Tests only become useful when you have a reasonably complex program. The way that you can avoid students disliking testing is by not assigning it on projects when it isn't needed.

A specific way in which you could do this would be by combining all the project you would assign over the year into one larger cumulative project. Eventually, as they're writing code, you can be fairly certain that they'll induce bugs or begin to find manual testing to be a pain. Once that starts happening, you can introduce automated testing to relieve that pain. That way, they'll see testing as a way to save work rather than create more of it.

In addition, I think the issue may be with this part:

> TDD and BDD have high upfront setup costs in ... thinking up test cases for all the various scenarios.

If you are spending time thinking of test scenarios, you're doing TDD wrong. You should never just take time to think of test cases. You should think about how you want each new piece of code to behave, and then testing should be a way of writing down how you want it to behave. That's just good planning, and you should be thinking about that anyways.

> **Comments:**
> **username_0**: Wow, what kind of test could you even write for "Hello, World"? You're probably right but that's not the problem I'm describing. I'm talking about half-semester type projects done for real-world customers. Not exactly paycheck-worthy, but still full-fledged functioning web services deployed to real servers and everything solving a small need for someone in the community.  
> **username_17**: `assert "Hello World" == hello_world_method` I didn't realize the size of the projects being done. Would you mind editing that into the question?  
> **username_18**: IMO TDD isn't appropriate for bootstrapping a project. It's most useful for bug fixes: create a test that replicates the bug, make sure the test fails as expected, then fix the test.  
> **username_0**: I made an attempt at editing but I'm not sure what to change. The question really applies regardless of project size, setting aside the fact for the moment that TDD/BDD aren't appropriate for tiny projects. Beyond that, I think the existing "handful of weeks" covers it.  
> **username_17**: @G.Ann-SonarSourceTeam TDD is the process of writing failing tests, making the tests pass and repeating until the project is complete.  
> **username_18**: Yeah, I get that @username_17.  
> **username_19**: BDD doesn't required Cucumber, you can do it without a framework as long as you are willing to follow the precepts. Cucumber, SpecFlow, etc. all help you "compile" BDD into code easier. Learning to think in BDD terms helps.  
> **username_20**: @piyush Parikh This is exactly it.  It is a waste of time if the upfront cost is more than what it would cost to just brute force the logic.  You can't appriciate a testing or development methodology until you work on a project that's too big or complex for you to fit in your head at once.  

---

### Answer by username_11 on 2017-06-22. Score: 6

The whole point of TDD is to try and reduce the number of defects in software. If your students are confident enough to think that they won't benefit from automated testing, fine — but **have some tests prepared** to run on their code to ensure that it's actually correct. If they fail your tests (which you need not specify in advance), then their solution is not a complete, working one, and they need to go back and figure out what went wrong.

I imagine you could gamify this a little bit if you wanted — [I've talked about Codewars before](https://cseducators.stackexchange.com/a/695/2), which uses 'hidden' unit tests to see if your solution works or not. You could do the same with your students' submissions, but you might not even need to use a framework to do that. You mentioned web services — why not just [black-box test](https://en.wikipedia.org/wiki/Black-box_testing) it a little to see what happens when you put in unusual results — does it fail when it should? You could even try [fuzzing](https://en.wikipedia.org/wiki/Fuzzing) the code to see if completely random nonsense produces the right response.

Essentially: **make the costs in the class the same as in industry — defective code is not a valid solution to your assignments.** In a job, a serious bug might cost your employer a large sum of money. You could emphasise that in your classes, and show them cases where testing has not been done, leading to huge amounts of cost.

If you follow TDD, you shouldn't really be spending much more time testing, unless your students replace the *writing tests before writing code* with just *writing code without testing*. Otherwise, surely the costs are very similar in terms of time if the tests get written either way? That is, of course, ignoring the productivity benefits of having tests that you can rely on while writing your code, so TDD might even be *quicker*!


---

### Answer by username_12 on 2017-06-22. Score: 6

Give an assignment to write a function or class, and give stub code that includes tests. Initially all the tests fail.

Let the students know that these and other similar tests will determine score of their assignment. Encourage students to write further tests if they want to know their code is correct.

> **Comments:**
> **username_13**: This is a nice lab idea. Welcome to CSE!  
> **username_12**: Thanks! This happened to me as a student in a CS 2020 class, probably this is most effective at a specific level of complexity.  
> **username_14**: As a professional software developer, in my experience this is how a lot of real-world coding tests are given to applicants. The applicant is also encouraged to add their own tests, which often gives them a competitive advantage over applicants who don't do this.  

---

### Answer by username_15 on 2017-06-23. Score: 5

The point of TDD, like many of the other answers have been saying, isn't really to test the code and find bugs, but to codify your requirements.

Having requirements that are codified is useful when you have a *lot* of requirements that need to be tested that all intersect each other (like in many industry projects), and when those requirements are going to change very often (which is one of the key assumptions of Agile).

It would be tricky to recreate the first condition in a school setting. Instead, lets focus on the second one: Throughout the project, introduce new requirements that overwrite and contradict earlier ones.

They might start with:

> we need to do A, B and C.

Once they finish that, mix things up:

> we need to do A, C, E and F. Instead of B we need to do D instead. And
> D shouldn't change how A and C work.

If they have good unit tests, it should be relatively easy to refactor and change their implementation. If they don't, they'll have a bad time trying to wade through their legacy code.

> **Comments:**
> **username_16**: The first paragraph is the key. TDD is driven by requirements. You test *requirements* not code. In fact, you start with a single requirement and write one test. Then make the test pass. Add another test for another requirement and get that to pass. Repeat until all requirements are passing. And then I wish I could up-vote this answer again for *changing* the requirements — the second key point to understand!  

---

### Answer by username_6 on 2022-10-13. Score: 2

I always have mixed feelings about TDD. If TDD is to emphasize the important to writing test code, yes by all means. But if TDD is to make you to write test code **before** implementation, **NO** I am totally against it.

There is a lot of exploratory & discovery in the development process and only when you actually implement something (through experiment and iteration) you will know what good tests should look like. To exaggerate my point a little bit, if my Function X should take a name and output a greeting with that name, then writing the test code beforehand for my Function X sounds pretty sweet. Anything more complicated than that will make writing test code beforehand quite pointless. You may also refer to [Test-Driven Development is Fundamentally Wrong](https://hackernoon.com/test-driven-development-is-fundamentally-wrong-hor3z4d). There are only some rare occasions that I find writing test first may make sense, one of them is to implement a homegrown bitarray (one of my assignments to the student) because even I have not figured out how to implement it I know what bitarray should behave so I can write test code first.

But this is a site for teaching and my answer is not to argue with others. Part of reason I answered it is I saw your words "*Even though the teachers **invariably encourage it** and present it as a useful strategy*".

As a teacher I will first emphasize the importance of writing test, then introduce TDD. But I emphasize that I am personally against writing test before implementation, but there are also many people embrace that idea, you probably need to try it yourself to figure out whether that is for you or not.

One of teacher's job to make students's eye open. So I may even go further (not for high school students) to mention that even we all agree writing unit test is a must but there is a crazy company called Tictok that they don't really write unit test and they still makes a huge success, check here for the detailed "[5 crazy things about working for Tiktok](https://www.youtube.com/watch?v=RNUrZFkHXlo)"(youtube video) or here, [the text version](https://twitter.com/LucasOuYang/status/1493408428626100226) . The point here is that there are many ways to do things and your job as a student to experience as much as possible.

--- update ---

After reading "[Chrome, 10 years later](https://neugierig.org/software/blog/2022/12/chrome.html)" I got another surprise, just like when I watched that Tiktok video. It makes me think again is UT really that important?

> Working with Apple.
>
> In retrospect I enjoyed this a lot, for two reasons. One is that
> getting code review from experienced engineers is one of the best ways
> to grow as a programmer, and the Apple engineers came from a totally
> foreign engineering culture — no unit tests! no comments! — that also
> was clearly producing a high-quality product.

> **Comments:**
> **username_3**: The problem with post testing for students is that once they write the code they are too likely to write tests that test exactly that code, not whether it meets the spec. It is too easy to miss boundary conditions and such, for example.  
> **username_3**: And for professionals, it is too easy to just ignore the testing in light of pressing schedules. No time to get it right, but plenty of time (needed) to fix it later.  
> **username_6**: That is one of points in [Test-Driven Development is Fundamentally Wrong](https://hackernoon.com/test-driven-development-is-fundamentally-wrong-hor3z4d) "Because the same blind spots that I had in design will appear in my tests".  "No time to get it right, but plenty of time (needed) to fix it later." is indeed a problem I hit many times and I don't have a good way to fix that too.  
> **username_7**: *"But if TDD is to make you to write test code before implementation,"* **--** TDD is **not** writing tests before the code.  
> **username_6**: @TimothyTruckle well, many say it is.  
> **username_7**: @Qiulang邱朗 those are wrong.  

---

### Answer by username_7 on 2017-06-22. Score: 2

The first mistake teachers usually make is not changing the point of view:

Unittests should be recognizes as "verifies *what my code does*" and **not** as "verifies my code *is right*".

Unittests are *executable specification*. With your set of unittests you can *prove* which parts of the requirements you really implemented.

One way to teach that to students could be like this:

* Split you students in teams of two.
* give each team a separate task to implement. This task should be too big to be completed.
* force half of the teams to do TDD, let the others go without tests.
* at the last day let the teams change their results so that TDD teams get the task of another TDD team and the "no tests" teams also change their results.
* let the teams work on the inherited project for half a day.
* after haft of the day do the same change as in the morning but this time give the TDD teams a "no tests" project and vice versa.
* Let them start with the same project state as in the morning and complete this newly inherited project.

The lessons leaned will be:

* without the unittests you first have to learn what the code already does by *manually* testing it. This is some effort even for small projects.
* with unittest in contrast you can simply *read* what the code already does and start implementing new behavior right away.

> **Comments:**
> **username_8**: Welcome to CSeducators Stack Exchange! `unittest`  it Python specific, and if the class if based on Python this could be a good project. Could the same project concept be developed to apply to any language?  
> **username_7**: @GypsySpellweaver I don't see why this should be restricted to any language.  
> **username_5**: This is a great idea, but as some of the other it doesn't really works when you don't have days and days...  
> **username_7**: @username_5 You are right, but TDD isn't something you can learn in two hours. TDD is a **skill** that needs to be developed and trained.  
> **username_5**: @TimothyTruckle definitively, I've managed to find an alternative, I'm showing them the technique live in class, and asking them afterward to do that on exercises that goes from very dummy stuff around string and then goes up to database insertion, rest api testing, sudoku grid verifying and that kind of stuff. And after that we get into the project where I ask them to use tdd and develop a simple api, for instance this year we made a very stupid copycat of pastebin.  

---

### Answer by username_3 on 2017-06-25. Score: 1

I'd like to add two notes. First is that if **you** write both the unit tests and the code, then all they test is that the code does what **you** think it is supposed to do, not what it is *actually* supposed to do. That is why Acceptance Tests are also used in agile development to test that the code does what the client/customer thinks it is supposed to do. With an imperfect understanding of requirements (or an incomplete test suite) you can pass all the tests and still not have a valid program. Also, if you write the tests *after* the code, then all they test is that the code does what the code does. That is a waste of time, of course, except, perhaps, for regression.

Second, in the context of a course, if you are lucky enough to be able to project a computer screen for all to see then you can spend part of a class period developing a small application (100 or so lines) in front of the class, perhaps with a student "navigator" showing how TDD actually works. Bit of test, bit of code, repeat.

You can also expect that the number of lines of code in tests exceeds the number of lines in the application itself. That is normal. But if you use an adequate programming environment it isn't a burden. Especially since something like Eclipse will fill in the application method skeletons from what it finds in the tests (assuming JUnit, at least). Think of the test framework as your low level design space, where you design the public interface of your classes.


---

### Answer by username_9 on 2023-05-29. Score: 0

Any technique of reasonable complexity requires fluency and experience. People who use TDD/BDD are using it as one of the many tools. Starting a new project with these tools enabled should take a competent professional very little time. Minutes for small projects like utility libraries. So the idea that it takes "more time" is like arguing that riding a bike takes too long vs walking - if you don't know how to ride a bike efficiently and are just learning and are wobbly and falling a lot and don't feel safe. Same with TDD/BDD. For a novice it's just as big of a deal as learning to ride a bike. A year later they won't even remember why it was supposedly a big deal. It's just something you do.

Many programming environments make testing almost zero-effort. Say python doctests. Most Python IDEs let you run those tests from a keyboard shortcut, or a menu/toolbar control. Setup is minimal.

Tests also highlight how hard it may be to write bug-free software. Even "simple" library code may have serious bugs lurking within. If you don't test well, you'll only find them when things don't work or work flakily.


---

### Answer by username_10 on 2017-06-26. Score: 0

I think students might fail to appreciate the benefits of TDD if they are working primarily alone. They probably just view it as an impediment to doing the "fun stuff", up-front grunt work they have to do before they can start coding.

Even in the real world many developers fail to appreciate the benefits of thinking about testing up front until they've been through a few projects and see the chaos that can ensue when insufficiently tested code gets deployed to upper environments and/or production.

In the full software lifecycle, time will be spent identifying bugs and fixing them. If you employ TDD and write test-driven code, you spend the time up front. If instead you just start hacking away, don't test your code, and throw it over to the testing group, time will still be spent finding and fixing bugs. It might not be spent by you but someone, somewhere will hopefully discover your bugs through testing, filing bugs, and fixing bugs. But it's usually more time effective to think about it up front. So while spending time doing TDD may seem annoying, it usually leads to overall time savings from the perspective of the entire project.

TDD in my opinion addresses two challenges that are present on almost every software project:

1) It's hard to collect requirements, document them, and turn them into test cases with a sufficient amount of detail that the software can be tested against actual requirements. While it may sound simple, many requirements are identified through conversations, meetings, industry research, ideas, etc. In a team environment, not everyone is aware of every requirement. And usually business people don't make good developers, developers don't make good testers, and testers don't make good business people, but all 3 groups have to work together. And nobody wants to write a super long and comprehensive requirements document and try to keep it up to date, and documentation tends to become obsolete immediately. Test driven development tries to address this by making every developer and team member part of the solution.

2) This last point is probably the most important point, many developers prefer only to do the "fun stuff" which is the coding, and have a tendency to assume that things like testing, accuracy, performance, integration, etc. are "someone else's problem". They can develop a mentality of writing code, doing limited testing, and then checking it in, assuming that someone else will somehow complete it. Some people say that this is the difference between being "done" and "done done". Software needs to be "done done" before it can work correctly but many developers only get it "done". TDD serves to address this problem by introducing a different mindset to the team, to make every developer aware that their code must be tested, and requires them to understand the context within which their code was developed and participate in all aspects of the software lifecycle and not just the coding.


---

### Answer by username_1 on 2023-03-24. Score: 0

When I was in industry, my boss said to me: this test driven development thing, [that we introduced recently] its real value is not that it finds bugs, or that we can re-factor without fear. The real value is that it saves us time, because it makes us think before writing the code.

# How to encourage its use

For the project, give them code that is already weeks into development, complete with unit-tests. Then, have them add features to the code. Using TDD.


---

