This book started off as a magazine article for a popular conference, No Fluff, Just Stuff. The article became a presentation, then the presentation became a book. It became evident early on that Scala had something good going on when it came to testing—not only with its variety of quality open source software, but also with automated test generation.
This book revolves around music, albums, artists, and bands. It makes the topics less dry, even though testing is wonderfully exciting, and it includes music from different generations. So anyone alive today will likely encounter a band or an artist that they will like. Music is universal, and relatable to most people. Using music in techical books as examples is not new: two of my favorite O’Reilly titles, Hibernate: A Developer’s Notebook and Learning the bash Shell, 3rd Edition used music in some of the examples, and I loved the idea so much I use it in constantly in teaching, in speaking, and of course in writing.
Much of the production code is simple—some might say pedestrian. The intent of the book is not to impress with overly fanciful or verbose production code, but to focus on testing code. As for the testing code, I also try to keep that simple, but I always provide some extra explanation if the code becomes unfamiliar or esoteric.
This book assumes some Scala knowledge, but recognizes that readers might not know all the nooks and crannies of the language. Therefore, all that is required is basic familiarity. And some Ruby and Python programmers may wander over to learn something different. For those groups, perhaps a quick introduction to Scala is in order. This may be fairly simple for Ruby and Python developers. I believe they are more apt to understand Scala concepts than Java programmers, since many of Scala’s language constructs have been used in Ruby and Python for years.
If the reader still does not feel that comfortable with Scala, either visit the Scala website for tutorials, read Dean Wampler and Alex Payne’s book, Programming Scala (O’Reilly), peruse the Daily Scala blog or attend some great conferences, many hosted by O’Reilly, that cover Scala.
Another learning opportunity is learning Scala through Scala Koans. Koans are small, Zen-like interactive lessons, meant to foster learning without overwhelming detail. Each lesson is short and comes with its own bite-sized epiphany. New koans are added all the time, and is a fantastic way to learn the language. The koans by yourself which is the lonely way to go, or at a local conference where it is interactive and conducive to more questions and answers.
gradle. This chapter covers basic commands, using interactive mode, packaging, and using SBT’s history.
ShouldMatchersdomain-specific languages (DSLs), and how to incorporate some of the popular Java-based frameworks, like JUnit and TestNG. This chapters also covers strategies for creating test fixtures with ScalaTest.
This book enhances the Scala language with standard test-driven development practices, highlighting the best testing tools today. This book will cover both the ScalaTest and the Specs2 testing frameworks, which help you create quick and easy tests. Testing is also often the most overlooked aspect of introductory programming language books. This book is dedicated to mending that gap.
We will run all these tests using Simple Build Tool (SBT). SBT is similar to some earlier build tools and competitors: Maven, Gradle, and Buildr. What makes SBT highly attractive is its ease of use and the small size of the build file. Type a few lines of code for your build file and you’re off and running on your project. We will also cover SBT’s wonderful triggered execution feature, which complements test-driven development by building and testing code whenever a file is saved.
ScalaTest and Specs2 are two of the most dominant testing frameworks for Scala around today. Each framework has a different intent and goal, but they share the same ideal of making testing concise, and they both leverage the Scala programming language to make testing easy and fun. Testing frameworks are nothing new, of course, and have been used with other programming languages for years. Those familiar with other programming languages and their testing tools will find some similarities with Scala’s current testing tools. ScalaTest and Specs2 borrowed ideas from Cucumber. But upon these shoulders of giants, Scala testing systems have also stepped out on their own and created some of the most mind-blowing testing tools found in any language.
Testing in Scala will also illustrate mocking code, so as to keep our tests isolated from large subsystems and networks. Mocking is, in essence, creating a substitute for various objects to isolate tests from volatile elements of their environment (such as the contents of databases) and to help unit tests run fast. This book shows how you can use Scala with Java-based mocking frameworks that have been used for years by Java programmers, EasyMock and Mockito. We will also introduce you to a new framework, ScalaMock. Formerly known as Borachio, ScalaMock was inspired by Java’s EasyMock and Mockito but takes their work further, even offering support for mocking final classes and Scala objects.
Following mocking, we will also generate a massive battery of prefabricated test data using Scala Check, which is borrowed heavily from the Haskell programmed testing framework called QuickCheck. Scala Check has preconfigured formulas to generate strings, numbers, and other various objects automatically. Scala Check also offers formulas to generate your own custom test objects.
This book will be organized in a TDD fashion: test first, fail; test again, succeed maybe; test again, succeed, and so on.
Because Scala is a deep forest of coding possibilities, my intent is to start on familiar ground, with the imperative programming paradigm, and work our way to the Scala functional programming paradigm, discovering some things about functional programming along the way. I will describe some Scala calls that may be obscure, either to introduce you to some constructs that you may not be familiar with, or as a refresher for those that are familiar with Scala.
All code in this book is compiled using JDK 1.7.0, Scala 2.9.2, SBT 0.11.0, ScalaTest 1.8, Specs2 1.12, ScalaCheck 1.10, and ScalaMock 2.4.
Test-driven development is the art of architecting software by specifying a requirement through a test before writing production code. There are many advantages to writing software in this manner. One is that you define what the software needs to do before setting it down in the program. The methodology gives the developer an idea of what the object should look like and be used for before it is built. This is the same simple idea as having someone hold up a picture for you before you commit any nails to the wall. During this time of reflection, you may decide that picture is the wrong size, the wrong color, too high, or too low. How does this translate to software?
Test-driven development starts with tests, each meant to define a single purpose such as “Write customer data to a database”, “Move a sprite to the corner of screen,” or “Send out notifications that a meeting registration even has occured.” The programmer writes the test using the class in question as if he were a developer using the API. Consider how a user would instantiate the object, etc. What problems would the end user encounter by calling the methods? What errors or exceptions should the end user expect?
The class and its methods don’t have to exist when you create the test. In fact, while you’re creating the test, you may decide to move methods around, remove them, or add new ones.
After developing the test, create the shell of the class and methods with no body. The point of this exercise is to start the test in a failed state. There is no point to running tests that always succeed even when code is missing or incorrect; you want to make sure a test complains when the code it is testing doesn’t work.
Once that has been established, add the data types, variables, and method body required to pass the test. At the first attempt, the test may still not pass; that’s OK. Further attempts should yield success. When a successful state has been accomplished, if there is a sense that more supporting methods are needed for the class, add another test, add the method signature without the implementation, make the test fail, and then add the production code to satisfy the test.
The adage “Don’t throw good money after bad” also plays an important role in test-driven development. Developing a test may clue you in that the class you’re planning to test will be irrelevant or misplaced in the project. The more test-driven development is employed, the more tuned in the developer will be to detecting any “code smell”. In the end, don’t be afraid to throw it all away if the test and its corresponding production class doesn’t pass the smell test.
Another point that programmers often overlook is that unit tests are to be isolated. Unit testing in test-driven development is not meant to test other external dependencies, like networks and databases. Many frameworks and developers will hijack the term “unit testing” to test their code against an application server or other large networks. Testing with other large systems and objects is properly labeled integration testing and is generally done after the initial unit testing has been performed. To isolate unit tests from large systems, so you can test code without actually making calls to these large systems, employ mocks and dummies to interact with the subject under test.
After the initial test and production code produce successful results, turn to refactoring. Refactoring is changing the production code to get rid of any duplicate blocks, combine methods that repeat themselves, rename methods and variables to make their names consistent, and move methods between any parent class or move them to each child class element.
During this phase, tests will be used as a guide to alert the developer that the code still works. Refactoring is perhaps the most important reason why unit testing is so vital. Since there is a harness for the code being written, you can make changes with confidence.
Another benefit to test-driven development is that an organization can separate development teams while they share the same interface. Both teams can agree on certain shared traits and models, and then go off on their own intensive paths where one team implements the trait or interface and the other codes up objects that depend on the trait or interface. For instance, two teams could decide on the methods needed for data access, after which one team creates a data access object (DAO) for an Oracle or a MongoDB datastore, while the other team works on the business methods using the DAO without actually needing a hard-coded DAO to do the work. When both teams are done, all objects can be developed together and tested as an integration test. The beautiful moral to this story is that large systems can be developed with very little waiting.
Test-driven development does take time—a lot of time, since bad habits die hard. From our first “Hello World,” programmers have begun with production code. It takes effort to rewire our brains to think in a “test, write, refactor, repeat” mind set. With practice, test-driven development will pay dividends not only in good code, but in malleable code that you can change on a whim.
Test-driven development lets you build only what you need. It is not surprising that after a few test-write-refactor iterations, code becomes reliable and stable—essentially a work of art.
The following typographical conventions are used in this book:
Constant width bold
Constant width italic
This icon signifies a tip, suggestion, or general note.
This icon indicates a warning or caution.
This book is here to help you get your job done. In general, if this book includes code examples, you may use the code in this book in your programs and documentation. You do not need to contact us for permission unless you’re reproducing a significant portion of the code. For example, writing a program that uses several chunks of code from this book does not require permission. Selling or distributing a CD-ROM of examples from O’Reilly books does require permission. Answering a question by citing this book and quoting example code does not require permission. Incorporating a significant amount of example code from this book into your product’s documentation does require permission.
We appreciate, but do not require, attribution. An attribution usually includes the title, author, publisher, and ISBN. For example: "Testing in Scala by Daniel Hinojosa (O’Reilly). Copyright 2013 Daniel Hinojosa, 978-1-449-31511-5.”
If you feel your use of code examples falls outside fair use or the permission given above, feel free to contact us at firstname.lastname@example.org.
Technology professionals, software developers, web designers, and business and creative professionals use Safari Books Online as their primary resource for research, problem solving, learning, and certification training.
Safari Books Online offers a range of product mixes and pricing programs for organizations, government agencies, and individuals. Subscribers have access to thousands of books, training videos, and prepublication manuscripts in one fully searchable database from publishers like O’Reilly Media, Prentice Hall Professional, Addison-Wesley Professional, Microsoft Press, Sams, Que, Peachpit Press, Focal Press, Cisco Press, John Wiley & Sons, Syngress, Morgan Kaufmann, IBM Redbooks, Packt, Adobe Press, FT Press, Apress, Manning, New Riders, McGraw-Hill, Jones & Bartlett, Course Technology, and dozens more. For more information about Safari Books Online, please visit us online.
Please address comments and questions concerning this book to the publisher:
|O’Reilly Media, Inc.|
|1005 Gravenstein Highway North|
|Sebastopol, CA 95472|
|800-998-9938 (in the United States or Canada)|
|707-829-0515 (international or local)|
We have a web page for this book, where we list errata, examples, and any additional information. You can access this page at http://oreil.ly/TestingScala.
To comment or ask technical questions about this book, send email to email@example.com.
For more information about our books, courses, conferences, and news, see our website at http://www.oreilly.com.
Find us on Facebook: http://facebook.com/oreilly
Follow us on Twitter: http://twitter.com/oreillymedia
Watch us on YouTube: http://www.youtube.com/oreillymedia
Foremost, I would like to thank Dawn Ramirez for everything I can think of.
Additionally, thanks go to O’Reilly and my editors Andy Oram and Maria Stallone, for their editing and guidance with my first book.
My tech reviewers were Bill Venners, Eric Torreborre, Rahul Phulore, and Josh Seureth. Thanks to them for many corrections and suggestions.
Thanks to Mark Harrah for developing SBT; to Bill Venners, Eric Torreborre, Paul Butcher, Cedric Beust, Kent Beck, Erich Gamma, and Rickard Nilsson for their excellent testing products; and to Jay Zimmerman, Venkat Subramaniam, Jared Richardson, Matthew McCullough, and Tim Berglund for networking, inspiration, and a wide range of opportunities.
And for their general support, many thanks go to Ruth Weiner, Kelby Zorgdrager, Bruce Budagher, Michael Budagher, Dianne Marsh, Jason Porter, Kito Mann, Ian Hlavats, Ken Helfer, Dwight Coles, Darold Parker, Gunnar Hillert, Daniel Allen, Mike Arms, Steve Wall, John Ericksen, Robert Engelhardt, Stephen Chin, Marek Novotny, Rodney Russ, Daniel Glauser, and Jeffrey Hulten. Of course family: Mateo Hinojosa, Lydia Hinojosa, Martha Arriola, Jose Arriola, Rosemary Hinojosa, and Hilda Ornelas.