This is a good book for any programmer who wants to learn unit testing. The examples are easy to follow. I did not learn anything new but it was excellent as a handout for several people at my company who knew how to code but have not heard of automated unit testing. Yeah, schools let new programmers out like that. 🙄
There's much less discussion about the art of unit testing in this book than you'd expect from the title. The book does cover various fundamental aspects, but is missing a breadth and depth of discussion.
The book will sometimes mention differences of opinion or technique, but never gets much discussion out of this as to why there might be differences (or what would make sense in different situations). The author's views don't get defended with depth more than "that's just my opinion, what do I know". The author explains "I used to write tests badly, but now I write them well." The book doesn't then discuss insights about non-obvious dynamics which emerge from unit testing in ways which seem good but aren't.
As an exception: the chapter on what the author thinks makes for a good unit test does provide examples, why he thinks the mistakes were made in the examples, what the implications of those mistakes are, and how to get around making mistakes like that. It's a better chapter than the others in the book.
Which is a shame because I think it would be valuable to read quality discussion about nuances of using unit tests. Otherwise why not just read the tutorial of whichever unit test or mocking library.
Still, there are ideas mentioned in the book that are somewhat above the fundamentals.
It doesn't help that book doesn't do a great job of making jokes. The jokes probably work fine in person, but in the book the same joke is repeated too often, and the jokes land.
A well written introductory book on the topic of unit testing. It covers a lot of ground, there is even a chapter on how to introduce unit testing to an organization.
But be wary. The book is a highly opiniated one. The author has strong opinions and does not shy away from presenting them. Of course that is not a bad thing but something to keep in mind.
A unit test should have the following properties: - It should be automated and repeatable. - It should be easy to implement. - It should be relevant tomorrow. - Anyone should be able to run it at the push of a button. - It should run quickly. - It should be consistent in its results (it always returns the same result if you don’t change anything between runs). - It should have full control of the unit under test. - It should be fully isolated (runs independently of other tests). - When it fails, it should be easy to detect what was expected and determine how to pinpoint the problem. - Your test contains logic that shouldn't be there: + switch, if or else statements + foreach, for, while loops A test that contains logic is usually testing more than one thing at a time, which isn't recommended - A unit test should be a series of method calls with assert calls, but no control flows, not even try-catch - Seperate the tests and production code project, because it makes all the rest of the test-related work easier. - The NUnit runner needs at least two attributes to know what to run: + The [TextFixture] attribute that denotes a class that holds automated NUnit tests. + The [Test] attribute that can be put on a method to denote it as an automated test to be invoked. - A unit test usually comprises three main actions: 1. Arrange objects, creating and setting them up as necessary 2. Act on an object 3. Assert that something is as expected - The Assert class has static methods and is located in the NUnit.Framework namespace. It's the bridge between your code and the NUnit framework, and its purpose is to declare that a specific assumption is supposed to exist - Name of test project: [ProjectUnderTest].UnitTests -- LogAn.UnitTests - Name of class in test project: [ClassName]Tests -- LogAnalyzerTests - Name of method: [UnitOfWorkName]_[ScenarioUnderTest]_[ExpectedBehavior] -- IsValidFileName_BadExtension_ReturnsFalse() - The red/green concept is prevalent throughout the unit testing world and especially in test-driven development. Its mantra is "Red-Green-Refactor", meaning that you start with a failing test, then pass it, and then make your code readable and more maintainable - Test code styling: + Naming convention. + Add empty line between the arrange, act and assert stages in each test. + Separate the assert from the act as much as possible (declare "result" variable) rather assert on a value than directly against a call to a function. --> It makes the code much more readable - [SetUp] attribute: it causes NUnit to run that setup method each time it runs any of the tests in your class - [TearDown] attribute: denotes a method to be executed once after each test in your class has executed - The more you use [SetUp], the less readable your tests will be, because people will have to keep reading test code in two places in the file to understand how the test gets its instances and what type of each object the test is using - Don't use setup methods to initialize instances. You should avoid it. It makes the tests harder to read. Instead, I use factory methods to initialize the instances under test - One common testing scenario is making sure that the correct exception is thrown from the tested method when it should be - Checking for expected exceptions: use Assert.Catch(delegate) instead of [ExpectedException] because [ExpectedException tells the test runner to wrap the execution of this whole method in a big try-catch block and fail the test if nothing was "catch"-ed. The big problem with this is that you don't know which line threw the exception. In fact, you could have a bug in the constructor that throws an exception, and your test will pass, even though the constructor should never have thrown this exception --> The test could be lying to you when you use this attribute - Ignoring tests: sometimes you'll have tests that are broken, you can put an [Ignore] attribute on tests that are broken because of a problem in the test, not in the code - Setting test categories: you can set up your tests to run under specific test categories, such as slow tests and fast tests, using [Category] attribute - Naming conventions of scenarios: + "ByDefault": when there's an expected return value with no prior action + "WhenCalled" or "Always": can be used in the second or third kind of unit of work results (change state or call a third party) when the state change is done with no prior configuration or when the third-party call is done with no configuration. Ex: Sum_WhenCalled_CallsTheLogger or Sum_Always_CallsTheLogger - Using stubs to break dependencies - An external dependency is an object in your system that your code under test interacts with and over which you have no controll (Common examples are filesystems, threads, memory, time, and so on) - A stub is a controllable replacement for an existing dependency (or collaborator) in the system. By using a stub, you can test your code without dealing with the dependency directly - Refactoring your design to be more testable: One way of introducing testability into your code base - by creating a new interface - 2 types of dependency-breaking refactorings, and one depends on the other: + Type A - abstracting concrete objets into interfaces or delegates + Type B - refactoring to allow injection of fake implementations of those delegates or interfaces - Extract an interface: you need to break out the code that touches the filesystem into a separate class. That way you can easily distingguish it and later replace the call to that class from your tests. Next, you can tell your class under test that instead of using the concrete FileExtensionManager class, it will deal with some form of ExtensionManager, without knowing its concrete implementation. In .NET, this could be accomplished by either using a base class or an interface that FileExtensionManager would extend - Dependency injection: inject a fake implementation into a unit under test - Inject a fake at the constructor level (constructor injection): In this scenario, you add a new constructor (or a new parameter to an existing constructor) that will accept an object of the interface type you extracted earlier (IExtensionManager). The constructor then sets a local field of the interface type in the class for later use by your method or any other - Simulating exceptions from fakes - Injecting a fake as a property get or set. When you should use property injection? Use this technique when you want to signify that a dependency of the class under test is optional or if the dependency has a default instance created that doesn't create any problems during the test - Use a factory class: The factory pattern is a design that allows another class to be responsible for creating objects - Use stubs to make sure that the code under test received all the inputs it needed so that you could test its logic independently - Interaction testing using mock objects - Value-based testing checks the value returned from a function - State-based testing is about checking for noticeable behavior changes in the system under test, after chaning its state - Interaction testing is testing how an object sends messages (calls methods) to other objects. You use interaction testing when calling another object is the end result of a specific unit of work - Always choose to use interaction testing only as the last option because so many things become much more complicated by having interaction tests - A mock object is a fake object in the system that decideds whether the unit test has passed or failed. It does so by verifying whether the object under test called the fake object as expected. There's usually no more than one mock per test - A fake is a generic term that can be used to describe either a stub or a mock object, because they both look like the real object. Whether a fake is a stub or a mock depends on how it's used in the current test. If it's used to check an interaction (asserted against), it's a mock object. Otherwise, it's a stub - The basic difference between mock hay stub is that stub can't fail tests. Mock can - Creating and using a mock object is much like using a stub, except that a mock will do a little more than a stub: it will save the history of communication, which will later be verified in the form of expectations - You aren't writing the tests directly inside the mock object code, because: + You'd like to be able to reuse the mock object in other test cases, with other asserts on the message + If the assert were put inside the handwritten fake class, whoever reads the test would have no idea what you're asserting. You'd be hiding essential information from the test code, which hinders the readability and maintainability of the test - It's perfectly OK to have multiple stubs in a single test, but more than a single mock can mean trouble, because you're testing more than one thing - Having several asserts can sometimes be a problem, because the first time an assert fails in your test, it actually throws a special type of exception that is caught by the test runner. That also means no other lines below the line that just failed will be executed - It would be a good indication to you to break this test into multiple tests. Alternatively, perhaps you could just create a new EmailInfo object and have the three attributes put on it, and then in your test create an expected version of this object with all correct properties. This would then be one assert - One mock per test. Having more than one mock per test usually means you're testing more than one thing, and this can lead to complicated or brittle tests - Isolation (mocking) framework: is a set of programmable APIs that makes creating fake objects much simpler, faster and shorter than hand-coding them - A dynamic fake object is any stub or mock that's created at runtime without needing to use a handwritten (hardcoded) implementation of that object - There are 2 common scenarios: tests run as part of the automated build process and tests run locally by developers on their own machines - The safe green zone: Locate your integration and unit tests in separate places. By doing that, you give the developers on your team a safe green test area that contains only unit tests, where they know that they can get the latest code version, they can run all tests in that namespace or folder, and the tests should all be green. - There are the basic 3 patterns based on test class inheritance: + Abstract test infrastructure class + Template test class + Abstract test driver class - Refactoring techniques that you can apply when using the preceding patterns: + Refactoring into a class hierarchy + Using generics - List of possible steps for refactoring your test class: 1. Refactor: extract the superclass + Create a base class (BaseXXXTests) + Move the factory methods (like GetParser) into the base class + Move all the tests to the base class + Extract the expected outputs into public fields in the base class + Extract the test inputs into abstract methods or properties that the derived classes will create 2. Refactor: make factory methods abstract, and return interfaces 3. Refactor: find all the places in the test methods where explicit class types are used, and change them to use the interfaces of those types instead 4. In the derived class, implement the abstract factory methods and return the explicit types - The tests that you write should have three properties: + Trustworthiness: Trustworthy tests don't have bugs, and they test the right things + Maintainability + Readability - Together, the 3 pillars ensure your time is well used. Drop one of them, and you run the risk of wasting everyone's time - Writing readable tests: + Naming unit tests: When I call method X with a null value, then it should do Y + Naming variables: don't use magic number like -100, replace with a readable variable like COULD_NOT_READ_FILE = -100 + Creating good assert messages + Separating asserts from actions - Code integrity: These practices are all part of code integrity: + Automated builds + Continuous integration + Unit testing and test-driven development + Code consistency and agreed standards for quality + Achieving the shortest time possible to fix bugs (or make failing tests pass) I like to say "We have good code integrity", instead of saying that I think we're doing all these things well - Working with legacy code (chapter 10): + Where do you start adding tests? You need to create a priority list of components for which testing makes the most sense: Logical complexity, Dependency level, Priority + Writing integration tests before refactoring + Important tools for legacy code unit testing (page 212) - Design and testability
This entire review has been hidden because of spoilers.
Disclaimer: I already have some experience with unit tests and I write them mostly in Dart (but I have coded in C# for some time as well).
I think this is a good beginner book if you code in C#. If you're a more experience programmer, I do think that Chapter 9 – "Integrating unit testing into the organization" is very very good.
However, I do have two big complaints about this book: - it is extremely coupled to C#, - it uses too much inheritance.
The book title states that it has examples in C#, not that the book is about testing C# code. I mean, I can read Clean Code and even though all examples are in Java, these are useful for people who code in other languages.
For example, the patterns used in chapter 7, which rely on having [TestFixture] annotated classes inheriting from some other class are unusable in Dart. Maybe this is useful in the sense that it's telling me that I could have more code reuse in my tests, and I, as an experienced programmer can figure out a way to do so. But I can't do it the way the author would, because the language will not allow me to.
The author also states that he likes using the "Extract and Override" pattern. Doing that is indeed more practical them refactoring to inject dependencies, but it's not SOLID and over time it will lead to code that is hard to understand. The author could have discussed more about this point.
This book is maybe useful to give to someone to persuade them why they should care about unit testing, but is next to useless at making you better at unit testing. XUnit Test Patterns is the canonical book for improving your unit testing skills.
کتاب جالبی بود که اگرچه به هدف یونیت تست نوشته شده بود اما گریزی به سایر حوزه های تست هم زده بود و مطالب جالب و مفیدی ارائه کرده بود. روش طبقه بندی موضوعات، بیان مشکل و بعد راه حلهای اون خیلی مناسب بود. متاسفانه هنوز ویراست سوم نیومده و این ویراست مال ۲۰۱۴ هست و در نتیجه مواردی که نویسنده در مورد فریم ورکها و ابزارها گفته و معایب و مزایاشون رو گفته، چندان به روز نیست در حالی که بخش خیلی جذابی از کتاب هست. البته مواردی که مطرح کرده معیارهای مناسبی برای مقایسه فریم ورکها و ابزارهای روز به دست میده. مثالهای کتاب چندان زیاد نیست، در واقع بیش از آموزش یونیت تست نویسی، به مسائل و نکات مهم و کاربردی و خطرات و اشتباهات پرداخته شده و برای همین فکر می کنم برای کسی که یونیت تست نوشتن رو بلد نیست یا تازهکاره، چندان کاربردی نیست. چون هنوز با چالش های این حوزه آشنا نشده و بعضی مباحث رو درک نمی کنه. امیدوارم بعد از ارائه ویراست سوم فرصت تورق اون رو داشته باشم.
I had little experience in unit testing before reading this book. After reading it, I discovered that I had terrible practices writing tests in general, and They weren't unit tests at all. The book is very practical. It gives you the experience to choose even what type of tests you need, gives you guidelines and warnings from some practices you may follow and setup a solid base for writing readable, trustworthy and maintainable tests. It is highly recommended for anyone who needs to trust in his codebase.
This title has been crossing my path for a number of years now, mainly through Amazon recommendations, and now also Goodreads recommendations. The second edition has been released a few months ago, and so I finally decided to purchase it and see whether I could learn anything from it. I have been a practitioner for many years, and felt that I have mastered the art, but if I learned anything from my years of experience, is that "there is always room for improvement".
Turns out that Osherove's book did not teach me anything new after all. The theory, techniques, and tools that the author outlined in his book I have developed myself through years of experimentation, failures, and research. If anything, I feel that the author could have expanded his title to cover additional subjects. For instance, anyone interested in mastering the art of unit testing would undoubtedly benefit to learn of patterns to manage a library of hand-coded stubs or stub factories that will certainly grow as the system gains more features and units that need to be tested. How to build stubs, for instance; how to organize them for maximum reusability and minimum duplication and management? Should one draw on the dubiously-named Object Mother pattern outlined by Martin Fowler perhaps, or maybe the Builder pattern?
This is not to say that this title is useless. Osherove progresses the subject in a highly approachable manner that will be quite helpful to a beginner. The author explains concepts and theory, and provides concrete code examples which encourage experimentation, and aid the learning process. Anyone starting with unit testing, or struggling with finding the optimal approach to unit testing, will most certainly benefit from this book.
This is a good book for those uninitiated in proper unit testing, but there are a lot o things I didn't like.
The book has a conversational tone, which can be very good, but there's a line writers should not cross. The author insists in using some dumb jokes throughout the book. I was pissed by the third time I read "you have three options: A, B, or quit your job".
Another problem with this book is that it doesn't connect the code examples in a manner that the build on top of each other. Most of the examples cannot be run and you have to figure out how to complete the missing pieces to make it work. If you don't intend to type and execute the code presented, this shouldn't be a problem.
Overall, I think the presentation of the concepts is spot on. But the issues with the examples was a major setback for me.
I'd still recommend this book to anyone who wants to dip their toes into unit testing waters.
I would like to give this one a perfect score since it explains a lot of stuff about Unit Testing and how can beginners start cleaner, maintainable code.
In the beginning, I find it hard and challenging to write Unit Tests myself, especially when making TDD due to the fact that I'm not used to the "Test-fail first" approach of coding. But as I go along the book and trying some samples(MULTIPLE TIMES), I was able to grasp the concepts the book was talking about. It took me a lot of time to understand it.
This book teaches you to write test first, and how to make maintainable tests. Furthermore, I believe this book also entails making your code cleaner through TOOD(Testable Object-Oriented Design) approach.
In the end, what the book stated totally makes sense. I highly prefer this to beginners to expert programmers alike.
I didn't get much out of this book. It's pretty thick to read, not something you can browse at a high level before diving in deeper.
The ideas in the book contradict the ideas in Software Engineering at Google on a fundamental level. Roy Osherove talks a lot about following the DRY principles in your tests and goes as far as suggesting you create a test API and use inheritance in your tests. Software Engineering at Google suggests not letting your tests become too DRY and to keep them simple and easy to understand. Roy Osherove talks about splitting up tests based on test class, or test feature, and gives several options, whereas Software Engineering at Google suggests splitting up unit tests based on behaviors. Personally, as you can guess from the rating I gave, I find myself more on the side of Software Engineering at Google, although it's just my 2 cents.
A must-read for every .NET developer. Anyway, Java and C# are similar, so it might be useful for Java devs too. The book shows many ways of writing a highly-testable code. Writing good test cases, what needs to be tested, and what not. How to structure our testing project/classes.
As with many other things, sometimes it is hard to know where to start to explore a new topic of interest, and TDD and unit testing itself was no exception from this. Fortunately for us, the above situation is no longer the case for the aforementioned subjects, as R. Osherove presents us with an excellent starting point with his book (I read the 2nd edition). Before going into (some) specifics though, it is important to note that this book is not about TDD (although it touches the subject), but rather about the technicalities of unit testing. And excellent technicalities it gives.
At first glance, the title might be a bit intimidating: "The Art of Unit Testing". To some, it might translate as "The Finer Aspects of Unit Testing", inferring, that you have to be a pro to gain any benefit from it. But, thanks to the author's good presentation skills, this can't be farther away from the truth, as people with any or no skills will equally benefit from it. As a matter of fact, it ensures this by starting from the very basic topics, like explaining what units, tests and unit tests are and what they are not, what makes them useful, what unit testing frameworks can be used and why they should be used, etc.
The book then dives into more serious stuff like making a very clean distinction between stubs and mocks, giving useful advice and examples when and how these should be used, showing how to refactor code for testability, when and how to use isolation frameworks, what types isolation frameworks have and what advantages/disadvantages they have, how to write and organize unit tests for reliability, readability and maintainability and more. The book finally touches finer aspects, like how to integrate unit testing into organization, what will make you fail or succeed in this quest, and how to be an effective constructive person in general. It also gives a good intro about how to work with legacy code from a unit testing perspective, and what considerations one has to make when deciding for or against testing parts of a legacy code base.
All in all, I'm very satisfied with this book, as it steadily builds a fair understanding of this very important programming topic from the ground, and does so by presenting plentiful (C#) code examples. Also, the code presented in the book is easily comprehensible even by those, who do not have any prior knowledge of the particular programming language (including me), as no language über-specific features are used. I must also emphasize the fact, that the author quite frequently gives very useful "further reading" recommendations throughout the book, which I personally think to be a very nice touch.
So, do I have some complaints? I honestly cannot think of one. I really enjoyed it from beginning to end, so the only thing left to say is that I highly recommend this to anyone interested in unit testing.
Kolejny wpis programistyczny. Książka ta kiedyś była polecana przez Maciej Aniserowicza (z 5 lat temu, przed jego zmianą paradygmatu działania). Pierwsza cześć lektury była bardzo dobra - ugruntowałem sobie wiedzę wyniesiona z lat praktyki. Niestety końcowe przemyślenia autora były dość chaotyczne. Mimo wszystko polecam.
Kilka wskazówek, które mogą się przydać, jeśli ktoś chce zwiększyć swoje umiejętności pisania testów:
-Assert.Throws() jest lepsze niż atrybut (adnotacja) Expected, bo dokładnie wskazujemy, gdzie, i w jakiej metodzie, powinien zostać wyrzucony wyjątek
-Fabryka do inicjalizacji obiektu, na którym wykonujemy testy, to najlepsze rozwiązanie przy tworzeniu testów
-Szwy to miejsca, w których można podłączyć różne funkcjonalności - namiastki (stuby)
-Nie wiedziałem ze w środowisku .Net jest tryb warunkowej kompilacji.
-Różnica między namiastką a obiektem - makietą (mockiem) jest taka, że mock zapisuje stan i zazwyczaj asercje są wykonywane na tym mocku i sprawdzają ten stan.
-Zaleca się tworzenie tylko jednego mocka na test i resztę namiastek. Więcej niż jeden mock oznacza, że testujemy więcej funkcjonalności niż jedną i powinniśmy rozbić metodę.
-Testy nie powinny sprawdzać czy zostały wywołane namiastki bo zakończy się to stanem "testing hell"
-Zamiast porównywać całe obiekty lepiej porównywać kilka właściwości za pomocą mechanizmow dopasowywania właściwości (String.contains etc). Inaczej wpadamy w tzw. “testing hell”
-Zbyt wiele makiet zmniejsza czytelność kodu. Poza tym pojedynczy test powinien sprawdzać jedną funkcjonalność “zamockowana” (najlepiej przez 1 mock)
-Gdy to możliwe należy unikać tworzenia obiektów makiet na rzecz namiastek (stosunek 1/20 to granica funkcjonalnych testów)
-Frameworki izolacji nazywane ograniczonymi to takie, które nie potrafią imitować metod statycznych, nie wirtualnych i prywatnych. Frameworki te po prostu generują kod danych makiet namiastek w trakcie trwania testu
-Bardzo dobry sposób testowania zależności od czasu to stosowanie w calym projekcie klasy, w której można arbitralnie wprowadzić czas
-Dodając testy jednostkowe do dużych projektów warto zacząć od testów integracyjnych, które sprawią, że na pewno dodanie testów jednostkowych i refaktoryzacja niczego nie popsuje
Roy Osherove’s “The Art of Unit Testing, Third Edition” is essential for software developers keen on mastering the nuances of unit testing. With contributions from Vladimir Khorikov, this book delivers a thorough exploration of unit testing practices supported by practical examples in JavaScript and TypeScript.
Strengths:
Depth and breadth: The book covers a wide range of topics, from the basics of unit testing to advanced techniques such as interaction testing with mock objects and handling asynchronous code. Each chapter builds on the previous ones, creating a cohesive learning journey.
Practical examples: The practical, hands-on examples in JavaScript make complex concepts easier to understand and apply. The transition to JavaScript and TypeScript reflects modern programming trends, making the book relevant for today’s developers.
Comprehensive approach: The authors do an excellent job of explaining the theory behind unit testing while also providing actionable strategies and best practices. The sections on integrating unit testing into organizational workflows are particularly insightful.
Weaknesses:
Steep learning curve: While the book is comprehensive, transitioning from basic to advanced topics can overwhelm beginners. A more gradual introduction to complex concepts might have been beneficial.
JavaScript focus: Although the JavaScript examples are well-executed, developers using other languages may find the heavy reliance on this language limiting. Including more examples in other popular languages could have broadened the book’s appeal.
Overall, It is a must-read for developers serious about improving their testing skills. It’s detailed, insightful, and packed with practical advice, although beginners might need to supplement their reading with additional resources.
I've seen this recommended many times over the years, and it's been sitting on my shelf for awhile so I finally went through it.
Chapters 1-2 are great as a introductory overview of unit testing (even if the nunit examples are out of date using what's now called classic assertions, it doesn't take a lot of work to update it to the modern assertion style). Chapters 3-6 (the entirety of part 2) are all over the place. Code samples change from section to section, making it somewhat hard to follow. Chapters 7-9 are good (especially Chapter 9 on pitching tests to your organization; it's easily the best chapter in the entire book). Chapter 10 shouldn't be here at all. It might have well just said "go read Working Effectively with Legacy Code" because that was my takeaway from it. Chapter 11 was fine, but felt as if it should have been earlier in the book.
All in all, roughly half the book was worth reading. The author is quite humorous, my favorite quote being "Seriously, if I catch another person commenting out something instead of deleting it, I will write a whole book titled Why God Invented Source Control". (Hear! Hear!)
While I'm reading this many years too late (after all, the 2nd edition released at the end of 2013 and I bought my copy in 2015), I'd have likely found this overrated even back then, and overall just can't recommend it.
I wouldn’t say I’m an expert at Unit Testing but have done it enough to understand the majority of points the author makes here. I think much of the things discussed I have learnt through experience but have only used the standard library "Microsoft.VisualStudio.TestTools.UnitTesting", Moq and XUnit. The author has worked on TypeMock so does mention it more than other frameworks but he does discuss alternatives too like Rhino Mocks and Moq. I think if you are new to Unit Testing, then you will find a lot of it useful, but I’d imagine other aspects are useful only when you have some foundation knowledge and experience in order to understand. The book is well written, and it wasn’t dry like you would expect a book of this nature to be. The author discusses when to use mocks or stubs, the difference between Unit Tests and Integration Tests, what makes a good Unit Test, common pitfalls etc.
The writer goes on sharing his distilled knowledge on unit testing and various patterns on making a maintainable automated unit tests, and by giving a clear recommendation on unit testing framework ,the author relief the novice unit tester approacher from the hustle of evaluating different unit test frameworks and giving the reader a solid introductory dose enabling him to adapt unit testing,the book also has a chapter explaining some of the pattern in dealing with introducing automated unit tests into a legacy code, being a technical book reading that is not accompanied with immediate implementation doesn't let you reap the most benefits of the advices and patterns displayed in the book, that's why I am planning on reading it for a second time.
One of the greatest content I have read in this topic. Before reading this book, I didn't have much experience in unit testing, however, the author was able to completely convince me to write unit testing, to feel guilty against any untested or untestable code. It made me fully understand the feasibility of unit testing and code quality. Of the best things about this book is that it emphasizes patterns, readability and code quality. It has lots of well-written examples. I agree that the author has strong strong opinion regarding some framework, but the core fundamentals of all frameworks are the same, when you understand NUnit and NSubstitute, you can easily switch to any other framework you like.
This book was a mixed bag for me. On the one hand, explanations are very clear and everything is easy to follow. On the other hand, it's organized quite haphazardly, with references back and forth and with no clear line to follow in order to progress step by step. Much of it reads like a collection of assorted blog posts, and some parts discuss very small details, such as features of different framework versions etc. Such fresh information should not be recorded in a book, since it will quickly go out of date.
If you're struggling with getting a grasp of unit testing however, this book will surely get you there.
This is a must read for anyone interested in writing good unit tests. The book introduces various concepts, tools, techniques and principles for unit testing. All are valuable.
You'll get most out of this book if you're using a static typed language. If you're using dynamic language, some sections of the book might not be applicable (e.g. constrained vs. unconstrained test framework, design for testability). However, there is still much value to take from this book even if you're using a dynamic language.
The book touches pretty much everything related to Unit testing on high level. It is a good book to start with and to get your head around the idea of unit testing.
This will not teach you to write all kind of test that you might write, but it will definitely provide you with all the necessary information that you would need to write any test.
The book of course has Roy's personality all over it. His sarcasm makes it fun and delight reading the book.
This is a great book on how to perfect your unit tests for your C# projects.
I really enjoyed this book, and got a lot out of it.
As someone who loves coding in a test-first manner (in the rare occasion that time permits), it is a great way to build your programs with the end result in mind.
Definitely recommend checking this book out if you are into unit testing.
Still trying to see where unit test fits in the scheme of things for the sorts of work I do. This book really wasn't all that helpful as its examples showed rather trivial fakes compared to anything I run across and suggested that anything more complex isn't really a unit test. If that is really the case then integration tests meet most of my needs better...
When i became serious with whole writing unit test thought process, I started with this book. It gave me good idea and direction and confidence to go about the actual act. This book will get you to speed about various aspect of unit test writing but you need to actually start writing to get the full benefit of the book.