Answers.Body: <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>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-10-13T18:42:45.817Z
Answers.Text: 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.
Answers.UserDisplayName: Buffy
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-10-13T18:45:01.203Z
Answers.Text: 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.
Answers.UserDisplayName: Buffy
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-10-14T02:30:20.667Z
Answers.Text: 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.
Answers.UserDisplayName: Qiulang 邱朗
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-05-25T20:13:08.610Z
Answers.Text: *"But if TDD is to make you to write test code before implementation,"* **--** TDD is **not** writing tests before the code.
Answers.UserDisplayName: Timothy Truckle
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-05-26T01:26:40.070Z
Answers.Text: @TimothyTruckle well, many say it is.
Answers.UserDisplayName: Qiulang 邱朗
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-05-26T17:22:56.990Z
Answers.Text: @Qiulang邱朗 those are wrong.
Answers.UserDisplayName: Timothy Truckle
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-10-13T08:28:56.503Z
Answers.LastActivityDate: 2023-02-20T10:07:27.813Z
Answers.LastEditDate: 2023-02-20T10:07:27.813Z
Answers.UserDisplayName: Qiulang 邱朗
Answers.Body: <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>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-06-22T22:28:43.960Z
Answers.Text: 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?
Answers.UserDisplayName: Gypsy Spellweaver
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-06-23T12:18:39.503Z
Answers.Text: @GypsySpellweaver I don't see why this should be restricted to any language.
Answers.UserDisplayName: Timothy Truckle
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-03-02T14:27:33.443Z
Answers.Text: This is a great idea, but as some of the other it doesn't really works when you don't have days and days...
Answers.UserDisplayName: YCN-
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-03-05T13:09:05.070Z
Answers.Text: @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.
Answers.UserDisplayName: Timothy Truckle
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-03-06T15:28:29.140Z
Answers.Text: @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.
Answers.UserDisplayName: YCN-
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-06-22T21:16:18.947Z
Answers.LastActivityDate: 2017-06-22T21:16:18.947Z
Answers.UserDisplayName: Timothy Truckle
Answers.Body: <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>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-06-25T17:45:25.967Z
Answers.LastActivityDate: 2017-06-25T21:22:51.510Z
Answers.LastEditDate: 2017-06-25T21:22:51.510Z
Answers.UserDisplayName: Buffy
Answers.Body: <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>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-05-29T20:15:16.307Z
Answers.LastActivityDate: 2023-05-29T20:15:16.307Z
Answers.UserDisplayName: Kuba hasn't forgotten Monica
Answers.Body: <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>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-06-26T14:23:45.233Z
Answers.LastActivityDate: 2017-06-26T14:23:45.233Z
Answers.UserDisplayName: Uncle Long Hair
Answers.Body: <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>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-03-24T21:44:49.797Z
Answers.LastActivityDate: 2023-03-24T21:44:49.797Z
Answers.UserDisplayName: ctrl-alt-delor
Answers.Body: <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>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-06-22T17:19:50.463Z
Answers.LastActivityDate: 2017-06-22T17:19:50.463Z
Answers.UserDisplayName: Aurora0001
Answers.Body: <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>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-06-22T22:00:22.190Z
Answers.Text: This is a nice lab idea. Welcome to CSE!
Answers.UserDisplayName: Ben I.
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-06-23T23:31:49.843Z
Answers.Text: Thanks! This happened to me as a student in a CS 2020 class, probably this is most effective at a specific level of complexity.
Answers.UserDisplayName: droid
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2020-11-11T14:57:51.337Z
Answers.Text: 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.
Answers.UserDisplayName: InvalidBrainException
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-06-22T21:50:46.183Z
Answers.LastActivityDate: 2017-06-22T22:00:05.247Z
Answers.LastEditDate: 2017-06-22T22:00:05.247Z
Answers.UserDisplayName: droid
Answers.Body: <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>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-08-20T03:19:39.107Z
Answers.Text: 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!
Answers.UserDisplayName: Greg Burghardt
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-06-23T16:58:40.650Z
Answers.LastActivityDate: 2017-06-23T16:58:40.650Z
Answers.UserDisplayName: FirstLastname
Answers.Body: <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>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-06-22T14:55:20.123Z
Answers.Text: 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.
Answers.UserDisplayName: Piyush Parikh
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-06-22T14:56:39.190Z
Answers.Text: `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?
Answers.UserDisplayName: thesecretmaster
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-06-22T15:04:11.250Z
Answers.Text: 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.
Answers.UserDisplayName: G. Ann - SonarSource Team
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-06-22T15:07:02.503Z
Answers.Text: 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.
Answers.UserDisplayName: Piyush Parikh
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-06-22T15:07:20.613Z
Answers.Text: @G.Ann-SonarSourceTeam TDD is the process of writing failing tests, making the tests pass and repeating until the project is complete.
Answers.UserDisplayName: thesecretmaster
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-06-22T15:59:45.823Z
Answers.Text: Yeah, I get that @thesecretmaster.
Answers.UserDisplayName: G. Ann - SonarSource Team
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-06-22T19:44:40.280Z
Answers.Text: 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.
Answers.UserDisplayName: AlG
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-07-18T22:56:26.700Z
Answers.Text: @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.
Answers.UserDisplayName: 8bitwide
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-06-22T14:47:50.090Z
Answers.LastActivityDate: 2017-06-22T15:00:19.523Z
Answers.LastEditDate: 2017-06-22T15:00:19.523Z
Answers.UserDisplayName: thesecretmaster
Body: <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>
  
Comments.ContentLicense: CC BY-SA 3.0
Comments.CreationDate: 2017-06-24T15:39:16.013Z
Comments.Text: 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.
Comments.UserDisplayName: ctrl-alt-delor
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2022-10-04T15:37:12.700Z
Comments.Text: Anything that forces you to think is good. Pretty sure anyway...
Comments.UserDisplayName: Scott Rowe
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2022-10-13T19:38:22.207Z
Comments.Text: 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.
Comments.UserDisplayName: Buffy
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2022-10-26T13:17:36.870Z
Comments.Text: 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.)
Comments.UserDisplayName: Raphael
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2022-10-26T13:19:53.283Z
Comments.Text: 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.
Comments.UserDisplayName: Raphael
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2023-03-02T14:23:18.573Z
Comments.Text: @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!
Comments.UserDisplayName: YCN-
Tags: <curriculum-design><student-motivation><student-perceptions><unit-testing><agile-development>
Title: How to overcome the TDD/BDD time fallacy
ThreadText: # 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**: @username_18 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**: @username_0 username_0 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**: @username_7 well, many say it is.  
  > **username_7**: @username_6 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**: @username_8 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**: @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.  
  > **username_5**: @username_7 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.
  
  
  ---
  
  