Testing Elixir (PragProg)

by @whatyouhide and @idlehands

Elixir offers new paradigms, and challenges you to test in unconventional ways. Start with ExUnit: almost everything you need to write tests covering all levels of detail, from unit to integration, but only if you know how to use it to the fullest—we’ll show you how. Explore testing Elixir-specific challenges such as OTP-based modules, asynchronous code, Ecto-based applications, and Phoenix applications. Explore new tools like Mox for mocks and StreamData for property-based testing. Armed with this knowledge, you can create test suites that add value to your production cycle and guard you from regressions.

Write Elixir tests that you can be proud of. Dive into Elixir’s test philosophy and gain mastery over the terminology and concepts that underlie good tests. Create and structure a comprehensive ExUnit test suite, starting from the basics, and build comprehensive test coverage that will provide safety for refactoring and confidence that your code performs as designed. Use tests to make your software more reliable and fault tolerant.

Explore the basic tool set provided by ExUnit and Mix to write and organize your test suite. Test code built around different OTP functionality. Isolate your code through dependency injection and by using Mox. Write comprehensive tests for Ecto projects, covering Ecto as a database tool as well as a standalone data validation tool. Test Phoenix channels from end to end, including authentication and joining topics. Write Phoenix controller tests and understand the concepts of integration testing in Elixir. Learn property-based testing with StreamData from the author who wrote the library.

Code with high confidence that you are getting the most out of your test suite, with the right tools that make testing your code a pleasure and a valuable part of your development cycle.

Don’t forget you can get 35% off the ebook with our Devtalk discount, use code ‘devtalk.com:023:

12 Likes

It would be nice if the ElixirForum discount could be reused.

1 Like

Nice, looking forward to reading this and learning some tricks.

1 Like

Might be best to wait until we have it out of beta. Should be towards the end of the summer. We have more content that will be added every couple of weeks. That said… you’re always welcome to support the authors and get the beta now. :grimacing:

2 Likes

There is a new discount available now… devtalk.com

Update: it is not a link, it is the new discount code!

3 Likes

It worked! Thank you!

Hey everyone, I am not sure on where to buy this book or not. I would personally like to know what the book considers a Unit test, which I assume is explained in chapter “Defining the Unit in Unit Test”.

This would help me understand if this book is more London or Detroit oriented (which school of TDD it preaches).

Has anyone bought this already? What does the book say?

1 Like

We encourage folks to define their unit as a discreet piece of their application that can be tested. If a local dependency is purely functional and well tested, don’t isolate your code. If the response from the dependency won’t be predictable, isolate your code. We cover a few different ways to isolate your code and we suggest Mox when you need to use a double.

We don’t teach TDD. All of the patterns were show are compatible because I TDD everything, but that’s not the point of the book.

Honestly, having read your posts, you sound like you’ve formed a pretty strong foundation and during opinions. I’m not sure how much you would gain from the book.

Don’t get me wrong, there are likely things that you might learn and like, but you might have to look for them between things you know or disagree with.

Happy to try to be more specific if you have questions.

1 Like

So, you consider a unit a piece of functionality in the code, like, lets say, a “User Login”. Logging in is a functionality that spans across various modules and dependencies.

You wouldn’t test the modules, you would test the fact a user can log in, correct?

That’s not what I am saying, sorry if there is confusion. We show several ways to isolate code and I specifically mentioned Mox, so if you want me to pick, I’d say we lean more towards London/Mockist but also don’t find value in forcing people to declare their style. Not every problem is the same and I don’t solve them all the same way.

There is plenty in the book about isolating code and you’re likely find that while our definition of a unit is intentionally vague (that section is about thinking about your unit and understanding the concept of a black box), our examples focus on small parts of an application, often just a single module.

As I mentioned, I have a feeling that you might pick up some useful stuff, but my sense is that you’re solid enough in your opinions that you either will know most of it and disagree with plenty.

We really did try to take a fairly neutral approach on a lot of things, though, so if you’re looking for “how do I test X?” you might be able to find answers.

3 Likes

Sorry, I never actually answered your question. I personally would likely test the modules but have an endpoint test that also proved everything works all the way through (happy path) and at least one error case. A login endpoint is pretty straight forward but most of the endpoints I’ve ever written have plenty of branching possibilities below the hood. So, instead of writing outside tests to hit every one of those branches, I isolate that code using whatever is the correct tool and exercise the branching logic. Then, the endpoint test would be to make sure that all of the pieces connect.

As far as which tests I start with, it 100% depends on the scenario every time. Sometimes I start really low-level and sometimes I start on the endpoint. The only thing that I’m dogmatic about is that I write my tests first.

3 Likes

I am close to finishing the book. I really enjoyed seeing different thoughts on what to test and how and why. Especially some of the iterative test creation tactics. I have already used some of what I learned in the book to write better tests at work.

I just ran into a disappointing situation where I was starting to write some code on a side project and wanted to take a look at the book code to see how some test setup was done in the book. So I downloaded the code bundle, installed the dependencies, and it doesn’t compile. Specifically the testing_phoenix tests. I saw MyApp used in several places instead of the actual app name, I fixed a bunch of those but then find other things that don’t compile, then I commented out some of those, and now more things won’t compile.

If there is a GitHub repo I’m happy to create a PR to fix a few of the errors, some are obvious, but I suspect that if there is a GitHub repo, it is already updated and working, but the code bundle on the PragProg book page is just out of date.

I still really like the book and think it is worth every penny even if it had no code bundle, but I would like it even more if the code bundle worked and I could use it for reference.

Eyeing this book, read some excerpts today and looks good. Any small discount code available perhaps? Already spend gazzilions on PragProg books :see_no_evil:

I was wondering: is everyone using just ExUnit for everything? Does it cover majority of needs or is it good to add something like Wallaby too?

Can you provide a little more info? Anything in NotSkull should compile. Anything that isn’t in that specific app likely won’t. You’re also welcome to hit me up at help@testingelixir.com.

I appreciate you speaking up and providing constructive feedback.

1 Like

Thanks for responding @idlehands

In this file:
testing_phoenix/not_skull/lib/not_skull/accounts/accounts.ex
These changes:

-defmodule MyApp.Accounts do
+defmodule NotSkull.Accounts do

-  alias MyApp.Repo
-  alias MyApp.Accounts.User
-  alias MyApp.ExternalServices.Email
+  alias NotSkull.Repo
+  alias NotSkull.Accounts.User
+  alias NotSkull.ExternalServices.Email

There is the same MyApp issue in testing_phoenix/not_skull/test/accounts/accounts_test.exs

In these files:
testing_phoenix/not_skull/test/active_games_test.exs
testing_phoenix/not_skull/test/game_engine_test.exs

The assert is_uuid/1 function is not defined.

And lastly, the error I gave up on:

(CompileError) test/game_engine_test.exs:575: undefined function first_guesser/0

This last one made me assume the code bundle was incomplete because this function is clearly not from a dependency that I somehow don’t have installed correctly.