Ask HN: Help me see why everyone seems to love TDD?

67 points by thuddle88 ↗ HN
I've been a developer working for large corporations for the past 4 who are more concerned with "fast" delivery than "correct" delivery. As a result of that, the concept of Unit Testing is somewhat foreign in the environment (I think we have somewhere around 40% test coverage, our unit test suite takes ~40 minutes to run on a dev machine, and new unit tests rarely get written). Unit tests aren't "valuable" to the customer, so they are pushed out in favor of "value" code (features) and the reliance on manual QA testers to catch defects (which doesn't happen).

Imagine you were hired as a consultant to come in here and fix our process. How would you sell TDD to the bosses/managers who only see it as extra work for the same value? I'll admit I'm a little fuzzy on the benefits as well. I'm slightly ashamed to admit that even on my side projects I'm like "I'm totally gonna do TDD you guys!" but that rapidly falls by the wayside.

88 comments

[ 2.3 ms ] story [ 132 ms ] thread
(comment deleted)
#1 A change in your current process must be "sold" in the business context of $$savings (faster dev cycle, lower number of bugs, lower cost of support) or increase in developer productivity/utilization or increase in customer satisfaction.

#2 Inadequate unit testing almost always correlates to greater defects in the support/maintenance cycle. So I would recommend gathering some data around it: for e.g., number of open support tickets, hours spent fixing such defects, regression testing etc etc. This must translate to either $$ or Hours "wasted" or additional head-count (required to deal with tickets).

#3 Identify a small but meaningful project to pilot out the TDD process. You will eventually have to develop your flavor of TDD within the constraints of your organization (people, tools, process...)

#4 Run the process for a few months and then compile the "before and after" data. Be prepared for disappointment. Process improvements are not always quick or visible at the surface.

#5 Management avoids things they don't fully understand. Most managers hear "better unit testing" and hear "more time and effort". Instead, they should hear "lower downstream issues, lower support costs, better builds, happier users".

So, can you help them understand the issue better? Just make sure YOU understand why unit testing matters to your company.

You're not going to get a much better reply than this. Speak their language, they will listen. Especially if you have access to historical data, it can be pretty easy to cherry pick some examples of where the improved QA would have had drastic savings.

People fear change, but no one wants to throw away money. Make them see the dollar signs.

I agree, this answer is pretty solid. I honestly think you could just start with #5. You can use the term "Technical Debt" when describing the debt that is created by not using unit tests. As in you are creating more work & cost down the road.

Here is 1 of many good Uncle Bob articles on TDD - http://blog.cleancoder.com/uncle-bob/2016/03/19/GivingUpOnTD...

This quote from the article is slightly off topic, but I think it is a great one you could tweak & use with Management:

"Look. Suppose you ask me to write an app to control your grandmother's pacemaker. I agree, and a week later I hand you a thumb-drive and tell you to load it into her controller. Before you do you ask me: 'Did you test it?' And my response is: 'No, I chose a design that was hard to test.'"

Before trying to sell TDD I would sell the idea of writing tests. That shouldn't be hard, it's mostly common sense.
You need to look at the time it takes to fix and retest defects caught in Test. As well as defects found and fixed once in production. Then you need to run a couple projects with unit testing and see if the bug counts go down. Or check the areas with unit testing versus not and see which have higher defects rates.
As you develop more on a software product it gets bigger, it gets more features and those features interact with each other. We can argue about whether its linear growth, sub linear or more but its going to keep increasing.

Every 2 weeks say you get a new release which has all the features of the previous releases + 2 weeks more. Given a constant supply of QA testers how do you manually test an ever increasingly larger featureset? You don't you skip the regression testing.

Almost all software studios without TDD working with short cycles do risk based testing, they test the new stuff and the things it might break. They don't test the major features if they don't think they were touched. So either you aren't refactoring and hence your code is rotting or you are and that risk based testing is missing areas that did have changes in practice.

TDD changes that, it turns the ever increasing QA cost of regression and new tests into development of tests and the growth is in machine running time for the tests. It flattens the human effort meaning your software is better tested over time and all the old features are tested every release reducing the chances of regressions.

If you don't release fast (12 months between releases) then its less of an issue because there is usually time to have a manual test team go at it and potentially delay release with bugs and regressions and such. But its one of the "G Forces", in order to develop at ever shorter cycles and be more agile to change you need to convert the human effort of testing into machine time and the only way we know of ensuring that happens is TDD.

First thought is the maintainability of the code base. If you are building an iPhone game that will be out of the charts in 3 months and will never be updated, then go ahead with feature code delivery and no tests. If you want your system to still be working in 2 years time and you still be able to add new features to it in 2 years time then you need tests.

The more confidence you can get in your code change the faster you can add features. Comprehensive automated, fast running testing gives you this in spades.

When tests become too slow I make the code and or tests faster until the tests complete in under a minute. Running tests in parallel can help. Even so, with a large set of tests that might be easier said than done but perhaps you can trim them down to the set that are most likely to be relevant and start off by testing just those? There are fancy ways of minimising exploration, working out which tests are most relevant for a given code change, but that is probably for later. Better to get started and then expand!
Taking 40min for the unit tests to run points to a problem, however, I've seen my fair share of "TDD geniuses/advocated" that love doing things that slow everything down (like writing hundreds of minuscule testings where 2 or 3 things could be tested in the same test, big setup methods, etc)
Hmm, having a test do anything more than one thing sounds like a functional or integration test.
Define "one thing"

Suppose you want to test a function that capitalizes the first letter of words in a string: I would test

'' => ''

'a' => 'A'

'aa bb' => 'Aa Bb'

3 tests, which does not mean 3 functions (that will have the overhead of setup and teardown)

I would make this a parameterized test for those common use cases and specific test for others ("o'tool" => "O'Tool").

The overhead of setup/teardown should be practically zero. Even having them as 3 separate functions should be take fractions of a millisecond.

The important thing is, it should be obvious why a test failed, you don't want more then 1 or two asserts.

Do the test run quickly, are they clear and readable, do they help find regression problems, is it reasonably easy to tell what went wrong when they fail, does the time and effort and peace of mind saved exceed that invested (over the life of the project, amortized, sometimes, for the value of iterating quickly)?

These are important questions, whether you call a test integration, functional, or unit, is not an important question.

To me, TDD is like a framework (Backbone, React etc). You can do it well and get a lot of value, and you can do it poorly and it serves no purpose. Ill provide an answer to your question, from a business perspective.

The value of TDD when done well is that you are ensuring (to a relatively strong degree, but not perfect) that you don't regress on issues. This isn't something that a human being can do when your system becomes sufficiently large and your introduction of features/deliveries accelerates.

For example, if it takes 1 hour for your QA team to 'system test' your application, and you introduce a new feature every day, that consumes a huge volume of resource over the course of a year. You also run the risk of human error, forgetting steps etc. At the end of the year, your QA team now take 4-5 hours per day to 'system test' your application. Its all they are doing all the time. This is pretty demoralising work.

If it takes 1 hour for one person to write tests that serve the same purpose. Those tests can run within in much smaller time frames and use far less resources than a manual 'system test'. That is a massive saving to the company as over the course of a year you will save hundreds/thousands of man hours and wont degrade morale.

TDD should give you confidence that your application is working as you intend it to be, its a tool and it can be used poorly, but when used well you should see the benefits.

(comment deleted)
Most importantly, for a larger code-base, unit tests allow a team to make structural and behavioral changes with much less risk of breaking existing functionality. This is especially true when one has a lot of business and domain rules to maintain. One small code change to core logic can have great impact.

Also, I have a lot of customers to support. Unit tests allow me to have confidence that I won't get 'the middle of the night call'. Largely because of them, my small team is able to work 40 hours a week and focus on adding new value rather than putting out fires.

Unit tests provide self-documentation. When starting to get familiar with new code, I first look for unit tests. If written properly, they provide great examples of primary use cases.

Finally, unit tests allow me to design better systems and interfaces. I can take a class or library and work on it in isolation from other parts of the system. Starting from consumer interface first, I can focus on what is really important and to make that interface much more usable. I can add parts incrementally without worry of breaking that core.

Like most things in software, TDD has trade offs. At first, implementation is much slower, and it requires significant knowledge of unit test best practices. I've seen a lot of bad unit tests: ones that don't test important things, ones that rely on external systems or libraries. I've seen developers get caught in 'unit test paralysis' - where they avoid tackling more important things because they are too focused on testing edge-cases, etc.

There's an entire art to unit testing. It requires pragmatism. For small projects, they're probably overkill. But, when your system grows to have many dependencies, some several years old, and someone has to make a change - ahhh, they're the best.

TDD came out of agile programming which is also more concerned with fast delivery than NASA-style correctness. It's a tool supposed to help you go faster.

If you want an agile unit test suite, it has to run in seconds, not minutes. TDD will make this very clear. If you have problems with the test suite being slow, you have to fix it!

A test suite that developers actually like to run is an enormous value, maybe especially for new team members. It gives you confidence when making changes and adding features.

A basic purpose of TDD is to make it obvious when code is hard to test, so that you're always encouraged to write units that can be unit tested without difficulty. That's a skill that takes some practice and learning, and you need to pay real attention to it. When your team understands how to do it, that's when the test suites start to make real sense, and it becomes pretty much a pleasure to write the tests.

I don't know about being a consultant but I'd like to say that comprehensive testing is a necessary standard part of professional programming just like serious manufacturers verify the quality of components. It can also reduce the stress and anxiety of developers which leads to a better work environment and better quality.

As a coder in a team with half legacy and half well tested code, I know it was a delight to work on the modules developed according to good TDD practice.

Test suite being slow: you shouldn't have to run all the tests all the time, just bask the code where you are working, run the full suite and take note of the failed tests, then just run constantly these and a few more while coding. Then run again the full suite before going to lunch.
That gets annoying when you're working on something that touches several parts, and if your tests are slow altogether they'll probably be slow enough to be tedious even when running just 10% of them.
"If you want an agile unit test suite, it has to run in seconds, not minutes. TDD will make this very clear. If you have problems with the test suite being slow, you have to fix it!"

To me this is TDD going putting the cart before the horse. Test driven design. Except you design so that the tests run fast. And the application design, is that actually considered?

Of course it's considered. It's not difficult to write fast unit tests if you follow the principles that make them fast. A fast test suite has lots of value, and doesn't conflict with good design—on the contrary.
I disagree with him but I'm also not a TDD fanatic in any way. Still, I find it useful to structure my code as units with few dependencies and minimal side effects, which makes unit testing a very appropriate methodology. I don't always do tests first, but I think as a methodology it's as reasonable as anything.
I've seen two main reasons why people love TDD.

First, testing is hard. It's a different mindset than development. TDD places testing first, which forces people to think about testing while doing development. From many accounts, this is an eye-opener which gets people to understand more about the whole process.

Second, it's a negotiation tactic. Developers usually have much less negotiation experience or influence in a project. It's all too easy to get something "working", then buckle under pressure to ship, even if the code isn't fully tested. Pressure is highest at the end of a project, so placing tests first means they won't be cut back as much. Also, developers can point to the methodology as a way to deflect the pressure from themselves.

Personally, I've tried TDD and found it to get in my way more than it's helpful. I mostly write my tests after writing the code, in an iterative style so the tests are usually written shortly after the development. (I have another stage of testing when I write the documentation and cookbook - that's where I usually find the code which is implemented "as specified", but where there sharp corners I didn't identify until I could use the code as part of a system.)

I have no answers to your underlying goal. One observation: you wrote "Unit tests aren't "valuable" to the customer". Have they considered value to the company?

Well, I'm not entirely sold on TDD just yet, but after applying it for a few years now, the benefits seem to be:

- Requires you to think about structure before you write the actual code. Code that is unit testable is usually better code. (but not necessarily)

- Requires you to think about the scenarios that you will support beforehand.

- Ensures that every file is unit tested. Without TDD you can have untested files. Why unit tests are great is another topic entirely.

- Ensures that tests cannot return false positives. TDD requires you to write and run your tests before any real code is written, so all tests should be red in the beginning. If you write your tests afterwards, your test could be green when in fact the code is incorrect.

What I don't like about TDD is that it pushes your code towards very easy to test code, which is not always better code. I'm more inclined nowadays to just start with the actual code, refactor iteratively until I'm satisfied, and then write the tests. This reduces the total amount of work, because otherwise you also need to refactor your tests every iteration, which only gets written at the end with my method. The downsides are that unit tests can be forgotten, or that you can write false positive tests. In my experience though, this rarely happens.

The most important part - imho - is to have meaningful unit tests.

Truth be told, I value solid integration tests more than unit tests, because they actually test the input/output of your system, which at the end of the day is the most important thing. Unfortunately integration tests tend to be more fragile and require more maintenance. On the other hand, they are more resistant against refactoring, while unit tests essentially have to be rewritten when any kind of refactoring happens.

Nowadays, I write both unit tests and integration tests, which is expensive to write and maintain, but in return they provide you with peace of mind and confidence, which is priceless imho.

Integration tests catch more bugs.

In fact unit tests are fairly low on the scale, according to this: https://kev.inburke.com/kevin/the-best-ways-to-find-bugs-in-...

Bugs caught is only one axis though, they other is effort. Unit testing is much lower effort, particularly for edge cases (what happens if dependency x throws exception) which may be hard/impossible with integration tests.
1. TDD can make delivery timelines more predictable, as there is less chance of regressions being introduced as new features are added. This predictability can allow a team to scale up to larger and more lucrative projects.

2. TDD enhances the capacity for necessary refactoring to take place which reduces the complexity of the codebase. By reducing complexity we can increase development productivity.

3. TDD itself can speed up development. A developer will necessarily have to test the feature he is building. Manually testing this feature will be time consuming and repetitive. An automated test allows the developer to quickly test the specific element that is being built in a repeatable and verifiable manner.

4. You are saying that the QA team is not catching all the defects. What else is new, but if you are delivering poor quality product to your customers then this may have commercial consequences in the future, if not already.

5. TDD is best practice and is necessary for the professional development of the team. If TDD is not supported it will negatively impact the ability of the business to retain good developers.

But aside from that, if we are talking about software development inside large corporations, we are probably talking about half-baked internal projects that aren't going to go anywhere due to a variety of reasons. The are probably a whole host of things to change within any large corporate of which the introduction of TDD is but a minor concern.

First of all, if your unit tests take 40 minutes to run (unless it's an insanely large codebase) then there's something wrong with your unit tests.

TDD isn't as much about being "correct" as it is about writing your API (and I mean internal API -- the classes and methods your software uses internally) first and then implementing the details. A side effect of TDD should be better designed software, which should in turn speed up your development.

The reason I brought up slow unit tests first is multi faceted. Most likely, they aren't really unit tests. You're probably testing the class in addition to the classes that your classes are touching (i.e. DB connections, etc). This is probably partially because unit tests are foreign to your developers and thus they don't know how to properly write unit tests, but additionally (more important to your concern about delivering software quickly) its probably a result of your classes not being easily testable. By making your classes more testable, you end up breaking things up, removing dependencies, programming to interfaces instead of implementations, etc.

Additionally, its easy to argue why delivering correct software helps deliver software quicker. If you deliver broken software, which takes down systems, developers need to spend time fixing the broken software. This time spent is extremely expensive. It disrupts the day, is a distraction, and depending on the extremity of the bug, can affect entire teams.

Beyond all that, knowing earlier on that your software is correct helps you move on to the next thing. When I say this, I don't mean verifying correctness after pushing to production. As an example, you need to update a database record based on some input from the user. Traditionally in order to do this you need to write a method on a model to do the updating, and you need to write a controller to call that method given query parameters, and you need to write a view to take user input and post a form. You may start with the model method, and it'll take you an hour to finally be able to test that your model method is working properly. If this fails, you have three separate places where it could have failed, so you need to look through the code to figure out where exactly it fails. Was it a forgotten csrf token? Did you forget to save in your model method? Did your controller simply not call the model method? With TDD, you'd write a test first to verify your model is working. Then you'd write a test to verify your controller is working (or not? some people don't test controllers). Then you'd write a test that your view shows the form and submits. As a result, you'll find out earlier and more specifically where issues lie.

All that said, its good to learn how to TDD with very strictly writing tests first, but in practice you need to understand the need to be pragmatic about it. It often doesn't make sense to write tests first, and you need to understand that its unrealistic to test every possible case.

The deal with TDD is you write twice as much code and you have less than half the bugs. As the project grows, it gets harder and harder to maintain and change unless you have good tests. Most projects without good tests that I've seen grow to a certain size and then become very difficult to make progress on because people are too scared of breaking things and the releases inevitably take a very long time due to all the QA.

One great thing about TDD is that I can pick up a project I Haven't touched in a very long time or am new to and work on it and as long as all the tests run, I know I didn't break anything. Without tests, the intimate knowledge of the requirements of a system tend to get lost and the project quickly becomes unmaintainable without a guru and active development.

I'd also say that having some tests from the start is much better than not having tests. The main reason for this is that to have tests, the code has to be developed with testing in mind. The second thing is that if you have a build system and a framework for writing tests, you can easily add new tests for tricky bugs or corner cases.

If you really want to go fast and loose, you should at least have a happy path integration test, a test for all the dao methods and at least a happy path test for the controllers. Any parts of the code that are tricky or algorithmically clever should also have tests. As your QA team runs into regressions, write tests for those regressions. This is a way I've found to amortize the test writing somewhat. It's important though that the test running is integrated into the build at these levels and is run before every release.

Problem is, tests don't scale well, if you project grows, your test suite grows too. The fear of breaking something will become the fear to not only rewrite the code but also having to rewrite an enormous amount of tests.

Also, having "more" things break other things in a big project is more of a modularization/encapsulation kind of issue, that doesn't get better or worse with tests.

At the moment I'm looking into static typing as alternative. I suspect this to be a "tests-in-code" kinda thing, which could eliminate many unit tests. Also with modern type inference and structural typing (I'm trying TypeScript) this could scale better than "write twice as much code".

It seems like you're talking about the problem of having overly fragile tests. Getting a test to break when something is actually broken is something that comes with experience and studying good tests.

For example, a novice test writer would serialize a Java object and compare it against a previously serialized object byte for byte. This would break as soon as there was a trivial change to the object. A better procedure would be to run pre-test and post-test assertions on the properties of the object that were actually important.

If you have good tests and change something and a bunch of the tests breaks, that simply means you broke a lot of stuff. At least you'll know what's broken instead of having it thrown back and forth over the wall between Dev and QA a hundred times to get it out the door.

I wouldn't do unit testing at all unless it was TDD. Effective unit testing requires a quick feedback loop with red and green pass/fail alerts.

I'd say really invest time creating a productive TDD environment for yourself first before attempting to convince business people. Buy into the dogma for several months. This should really give yourself an idea of the pros and cons of TDD.

Strictly speaking I don't do TDD because I don't write tests first. I write code first, then I write the tests. If I went tests first sometimes I would have to design the algorithm anyway because I wouldn't know what to test.

However, I tend to write tests very early as soon as some code runs. Why? Because without tests I would feel like driving a car at night without lights and with no brakes. Sooner or later I'll crash into something and discover that I'm way out of route.

The reason is the same if you do proper TDD.

I also use test coverage tools, to know what I'm not testing. Sometimes is not important, sometimes it is. Given constraints on time and budget it's important to have data to back the trade off you must make.

(Question to native English speakers: you do a trade off or you make one?)

About those 40 minutes: it's way too much. Even 4 minutes could be too much. Is your application that big or are you testing its parts many times with different tests? Maybe you could slim down the test suite. Unit tests for the single components and an integration test for all the application. In the case of a web application you would use one of the many tools that drive a real browser through all the pages of the app, one test per use case. That could be slow but the unit tests would be fast. You can run the unit tests on your computer and the integration test on a continuous integration server.

Edit: -do +make trade off

You make a trade-off. Do sounds weird, and I have no idea why. :)
I guess because we make compromises and make deals.
Thanks to both of you guys.
This is generally how I approach writing unit tests as well. Perhaps I'm doing TDD wrong, but I find myself running into the same problem as you that I often need to do too much design up front to write a test. The alternative is that I write the test using the simplest possible interface and then go back and continually change the test as I write the code. I've tried this but I haven't really found any benefit to this.

My approach is generally to write a passing test for a simple use case after I know that case is working. Then I'll write some tests for some more complex cases and fix any of those which fail.

The risk with this is that your test is possibly not checking the thing you want. I have often found a test that passed even when the code wasn't working. Writing the test beforehand, when you know it should fail, helps get around that. You expect it to fail, then write code, then expect it to pass.

I like to at least test my test by commenting out the bit I just added, or somehow manually breaking the code somewhere to check it really does fail when the code doesn't work.

I've found that if you lead by example, people will follow.
my personal style to design a system is to focus on design the domain model, I believe that this is an intuitive way for people to design stuff (not just software, also in math and ML). This is the reason why I am not sold by TDD which start with writing test cases first – how come people can tell what is going to test before they know what they are going to develop.

I tried some projects with TDD, but unfortunately, it is too counter intuitive for me to follow to design a system.

The last D is design...

Write your test as if the perfect domain model existed already, and then make it work. E.g. does it make more sense to write person.Age = 21, or person.Birthday = someDate. Alternatively, taking your math example, your tests are the constraints of an equation that your code solves.

We switched last year to start writing unit tests for all new code and refactoring old code to be testable and write tests for it whenever we go back and touch it. Here's the benefits we saw from doing this:

1) Development is not really slowed down by any meaningful amount. You might invest more time up front, but further development is faster. The time investment in unit tests at the beginning pays for itself very quickly. With anything of a reasonable size, especially anything that involves multiple developers, the unit tests will speed up development over all.

2) The obvious one; you find bugs faster. If you write thorough and good test suites, you will find bugs before you release the code (obviously) and you will find bugs when you go back and touch the code again. I'm not going to claim you'll find every bug and never release a bug into the wild again, because that's not true, we're human. But things will be vastly better.

3) Maybe most importantly, it forces you to think about your code more and write better code. In order to make your code properly testable that will mean that your code has to be properly divided up into testable units. That means goodbye monolithic code, hello division of concerns.

It's silly but if you're having a hard time convincing management, sometimes they respond to the fact that any "serious" development team at a "real" enterprise writes unit tests. Managers are sometimes very susceptible to pointing out that they're doing things in an amateurish way, because they like to think of themselves as professionals.

So, I'm seeing a few different things here...

1. There is a difference between selling unit tests and selling a development method that is guided by writing the unit test first. Unit tests are great for providing self-documenting code and examples. A developer can look at the test and see what is expected to use the code. Unit tests run quicker than integration tests, but both are needed. (With the right unit tests, you need a fraction of the slow tests.)

You sell unit tests as extending the life of the product by years because the developers in ten years will understand how the system works by its tests.

2. You sell test driven development to developers by doing it with them, side by side, and observing the output in the end. Test driven development is also called test driven design. By writing the test, making the test pass, and then clean up the code, you get a quick iteration loop that allows you to make changes as you go and know your tests have your back.

An experienced TDD developer develops at the same speed as a non-TDD developer, because the TDD developer develops the toolkit to write tests quickly. They get caught less in analysis paralysis because they can just make a change, see what it looks like, and know if it works because their tests pass or fail.

But just like when someone learns another programming paradigm, it takes time to get there. TDD is slow for most people because they never get good at TDD.

The disadvantage to those code bases is that making a design change can sometimes feel slower because the time to read the existing tests, understand which breaks need to be addressed by code and which need to update the test -- that can be drudgery. I've lived in 100% unit test code bases and it can be irritating to make a big change.

(Some TDD advocates say that your tests should never break, and you should work in abstractions that ensure that your tests never break. This can lead to designs I don't prefer and really weird intermediate states.)

My personal opinion? If you're in dynamic languages, you need more tests than in a statically typed language. If you're in a functional language, you need fewer tests still. The more your compiler will do for you, the fewer tests you need.

The biggest advantage of tests is that you can move (possibly new) devs on to unfamiliar parts of the code base and they can be reasonably confident that they aren't breaking things with their refactors.
Have you actually lived in a TDD world? Actually sat down and did the entire thing? I don't think it is worth it.

Tests are good. Fire manual QA team and hire people to write automated integration tests.

But actually designing your code around tests? It tends to lead to brittle systems that do a lot of dumb things. Write the code what works best, then add some tests around it where required. 40% coverage could be enough for some apps.

We have automated tests of all types, covering almost everything, but we still find use in our QA team. They also help us write BDD tests.
Sure, I think a QA team writing tests is good. I maybe think QA teams doing exploratory testing is good. The rows and rows of QA in cube farms doing regression testing? That is not good.
> Fire manual QA team and hire people to write automated integration tests.

From experience, this leads to coders coding-to-the-tests. It compiles, it passes, ship it. Does it doing the right thing under stress? Who knows.

Manual QA staff, proper QA staff, do crazy non-linear things that stresses code like customers do. I'll bet they would have caught that bug in the other front-page story about the animal feeders failing without an Internet connection; I had a tester who pulled-out the cat5 on many occasions.

I think I've said it before: automated tests are the entry test to the QA process, not the exit diploma.

So you talk a lot about stress testing. There is 0 reason developers can't code stress testing and add as a step in the release cycle.

You know why this never happens? Performance is never a requirement, almost always an afterthought. How many specs list required throughput or 99.99 percentile latency?

No one cares about perf until it's bad. So if we fix that, put in the spec... We can automate perf testing and perf monitoring. Sure have a perf team code this. But I don't need a QA guy to run a perf test for me.

It's not that, so much as manual testers will /notice/ that code is slow, and ask questions about it, whereas automated tests will run the script no matter what (unless someone thought about it in advance)

Likewise, you /can/ code an automated test to simulate sudden network loss, but a human will just randomly decide to try it, without someone pre-programming him

I don't understand why people seem to think that testers could or should be replaced by automated tests. I've worked a lot with test automation, and I find it super important to have automated tests for any long-living project, but one of their main purposes are to off-load the manual testers from doing repetitive regression testing, and focus on more creative exploratory testing - things that humans (well, some) are good at, but computers are not.

In addition, testers should play a central role when it comes to validating requirements - they typically catch issues and inconsistencies that would otherwise go unnoticed until $x has already been spent on going down the wrong path.

I have had people I trust a lot more than myself argue this. That humans are better exploratory testers than robots.

Totally agree that humans doing manual regressions is bad. I would almost argue that needing humans to do regressions means that something is broke in your coding / testing / deployment process. If page X must REALLY do Y and always work, why aren't you testing it on 30 browsers automatically? Even a very good human would have a hard time matching what you can code automagically.

I trust that there is something there though in humans for exploratory testing. And indeed I have worked with good QA people over the years that found awesome stuff. But I have also worked with many man QA that have added massive negative value to projects. Perhaps I let reality taint my taste of QA?

One thing is that a lot of testers are still working in a very rigid way. First, design and write down the test cases (based on a specification that is most likely flawed and incomplete). Then, perform the tests. Then, document the results. There is very little room for creativity and exploration in such a process.

This is basically what you do when you write automated tests, except the execution (and reporting) steps will be done automatically and repeatedly. Which is super valuable, but when a skilled tester goes at it, there will be ideas and crazy connections flying around everywhere. Even if many of these tests were to be automated (which in many cases really isn't feasible, considering implementation time/execution time/maintainability costs), you'd need someone to even think up the tests, and typically developers don't have the time or breadth of knowledge of their system to do it.

I used to work in a team with 5 developers and me as the tester. Besides finding tons of bugs - many of them very subtle - I became the one person who understood the product best since I was the only one touching all parts of it, so I was the one people came to for questions. Now, working as a developer, I do write automated tests, but I refuse to release anything our tester haven't had the time to test yet.

Ya the embedded tester thing. I have never really done that, but I can totally see a lot of value.

I HAVE had places where the team lead didn't code and basically acted as the embedded QA. That isn't terrible.

> Fire manual QA team

Terrible idea.

> and hire people to write automated integration tests.

Excellent idea.

I've been a part of many software projects, and unfortunately almost none of them took testing seriously enough. No, actually, none did.

I've tested software manually for years. I've found many defects I'm certain no reasonably complex automated test would have detected, because finding them was down to my global knowledge of the entire system's state or the superior ability of humans to detect patterns.

Don't underestimate what an experienced, cunning tester will suss out.