I can haz dependencies?

I hate IoC containers. Spring? Evil. Guice? The devil’s own work. Why? Because it leads to such slack, lazy, thoughtless programming.

Why the hate?

Ok, perhaps I better explain myself a bit. IoC is a great idea. What annoys me, is the way IoC frameworks end up getting used by normal people. I’ve ranted previously about how IoC containers lead us to implement anaemic domain models. The trouble is, once you have a hammer, everything starts to look like a nail. Especially those pesky fingers. Once you have a dependency injection framework, everything starts to look like a dependency that needs to be injected. Need to implement some business logic? First create a new class, test drive it, then make it injectable, inject it into the class where the calling code needs it, test driving it natch, then bingo – you just hit yourself on the finger.

Now I’ve got two classes, basically closely coupled, but the IoC container hides that fact from me. I see a nice, clean interface being injected in. Aren’t I a good little OO developer? No, you’re stupid and you’re lazy.

Before you know it, your class has a dozen or more dependencies, each of which have a dozen dependencies, each of which have a dozen dependencies, each of which… you get the picture. You’ve managed to build a rats nest of a dependency graph, little by little. What you’ve TDD’d isn’t a design. The technical name for it is The Big Ball of Mud.

An Alternative

Instead, I think dependency injection works best at application seams, at architectural boundaries. Say, for example, you’re building a web app. You’ve created a TradeEntryController that allows users to, well, enter trades. The TradeEntryController naturally has loads of dependencies on the rest of the system. It needs to fetch valid assets to invest in and prices, it needs to know what your balance is so you can’t buy more shares than money in the bank etc etc. A perfect example where life without an IoC container could become really cumbersome.

But, I don’t think you need one. I think what your controller needs is a few, specific dependencies – that define the architectural boundary the controller lives within. Above the controller is a HTTP request, a session and all that blah blah. Within it, is business logic. Below it is the database. So, the dependencies we inject should represent only the architectural context in which the controller operates. For the most part, this will be common to all my controllers – not just trade entry. Controllers for managing balances, lists of assets, user accounts – these all depend on knowing stuff about their session, and to be able to talk to the next layer down: the database (or in an n-tier setup, perhaps some web services).

So, why not just inject those dependencies?

public class TradeEntryController {
    public void setSessionManager(ISessionManager sessionManager) { ... }
    public void setTradeDatabase(ITradeDatabase tradeDatabase) { ... }
    public void setAccountDatabase(IAccountDatabase accountDatabase) { ... }
    public void setAssetDatabase(IAssetDatabase assetDatabase) { ... }
}

Then in my controller, I can fetch user information from the SessionManager; I can get the list of assets from the AssetDatabase; I can check the user’s balance via the AccountDatabase; and I can record the trade via the TradeDatabase. So far, so much the same as a normal IoC container.

So what’s different?

Rather than manage these dependencies via an IoC container. I think you should push them in manually. Yes, I’m suggesting you write your own dead simple dependency injection framework. What? Am I mad? Quite probably, but bear with me.

public interface ICanHazTradeDatabase {
    void setTradeDatabase(ITradeDatabase tradeDatabase);
}

public class TradeEntryController
    implements ICanHazTradeDatabase, ICanHazAssetDatabase...
{
    ...
}

public class ControllerFactory {
    public Controller createController(Class clazz) {
        Controller c = clazz.newInstance();
        if (c instanceof ICanHazTradeDatabase)
            ((ICanHazTradeDatabase) c).setTradeDatabase(tradeDatabase);
        if (c instanceof ICanHazAssetDatabase)
            ((ICanHazAssetDatabase) c).setAssetDatabase(assetDatabase);
        if ...

        return c;
    }
}

The exact mechanics of ControllerFactory of course depend on your MVC framework, but hopefully the idea is clear: when we instantiate a controller, we check it against a known set of interfaces and push in very specific dependencies. Is it pretty? Not really. Is it easy to write? Of course. Does it push dependencies into your controller? Well, yes. Where do they come from? Well, that’s an exercise for the reader. But I’m sure you can find a way to make ControllerFactory a singleton and instantiate all your dependencies in one place.

The Point

What, exactly, is the point of all this? Well, as a developer writing a controller – I can get easy access to all the dependencies that represent the architectural context I’m running within. The databases, services, message brokers, email server, blah blah blah that the application as a whole depends on. They’re right there – I just add the interface, one method and bang – ICanHazCheeseburger.

More interesting, is what I can’t do. I can’t decide that my TradeEntryController needs a TradePricingCalculator and inject that as a dependency. Well, I could, but I’d be making TradePricingCalculator available everywhere, and I’ve got a little more work to do than I would if I was using plain old Spring or Guice – I’ve an interface to create, a couple of lines to add to some scarily named GlobalControllerFactory. Why is this important? It adds some friction. It makes something bad hard to do. I’m forced instead to think about creating a TradePrices object and adding some functionality to it. I’m forced to have a rich domain, because I can’t just move all my functionality off into a TradePriceCalculatorVisitorFactoryManagerBuilder.

The choices we make and the technologies we choose make some things easy and other things hard. We need to think carefully about whether the things we make easy should be easy. It’s always possible to do the right thing, but sometimes we need to make it easier than doing the wrong thing.

Reading code

Writing good code is all about making it fit for human consumption. Any idiot can write code a computer can understand, it takes care to write code another human can understand. But what does it mean to make code easy to understand? Programming is a literate task – writing well requires experience of reading code and in particular reading well written code. But how do we read code? Do we start at the beginning, read line by line until the end? Hardly.

Writing Code

Let me start by asking a different question: how do you write code? You probably write a test, write a small amount of code to make the test pass, then refactor to improve the readability, design etc of your code. Little by little the functionality accumulates; little by little the design emerges from a sequence of decisions and refactoring steps. TDD is fundamentally a design activity. Although you may have an idea of what your design will look like, the actual design will emerge from a sequence of small, interdependent activities.

Reading Code

Now six months later I’m reading this same code. What do I do? Well, I might start by reading the tests – well written tests should help me understand the intent of the code in question and, if they are acceptance tests, tell me what the customer thinks is important. In practice, I find this a painful way of figuring out the important things about a system. If TDD has been followed religiously you’ll have approximately 3.6 billion tests, grouped in a number of different ways making it difficult to keep enough context in my head at once to make any sense of the system.

Instead, I probably have something specific I’m trying to do. I have a change request or a bug to track down. So I probably dive in and make some guesses about where to start. I can’t remember the code so it’s a needle in a haystack. I probably miss and have to wend my way through the code trying to figure out how it fits together. I need to get some kind of big picture – at least for the part of the code I care about, as soon as I work out what that means.

Inferring Design

What I’m trying to figure out is the design of the software. How do these 200 classes relate to each other? What are the bigger patterns that will help me figure out where I need to look. Now, if I had documentation, I could look at that. But 1. it’s probably out of date or missing 2. even if it’s there, I wouldn’t trust it anyway.

So instead I find myself scribbling in a notebook – drawing class diagrams and other doodles with boxes, arrows and lines going all over. But how do I infer the design? I’m trying to understand how some parts of the system interact with each other. I look for references to interesting methods, chasing up the call stack to see what’s interesting. I find interesting classes involved along the way and I click through into interesting method invocations to see if anything fun’s happening. All the time I’m bouncing up and down call hierarchies trying to fit the system together.

As my notes start to coalesce I’ve got some idea about the key classes I care about and their roles in the system – I might find one or two key classes and scan through the whole thing, to see what other responsibilities it has. All the time following interesting method calls and looking for references.

The problem

Reading code is frankly nothing like writing code. But if writing great code means writing code that is easy to read, it’s a damn shame that the task of writing is so fundamentally different from the task of writing. It’s not as if after I’ve written a class I can pretend to have forgotten how it works and try and infer it. The best I can do is make sure that the code itself looks superficially clean. Is the style right? Is it formatted neatly? Insanely superficial stuff that frankly won’t make any difference in 6 months when I’m cursing the idiot that decided 16 levels of method calls with similar names was a sensible design approach (me).

The solution

On a superficial level I wish we could stop dealing with code as text and instead work on the syntax tree, with automated formatting following my preferences – not yours. Then we can all have our own idiosyncratic way of having code presented without having to argue for the billionth time whether spaces are preferable to tabs (of course they are) or whether curlies should be on a new line (of course not, heathen!).

The craftsmanship ethic of writing clean, well factored code is a good step. It doesn’t tackle the fundamental problem that reading code is different from writing it – but reminds us to address some of the symptoms: a comment is a whole new method just dying to be extracted. A 100 hundred line method will be at least twice as easy to understand refactored to two 50 line methods. Make things clear and simple and maybe the code will be easy to understand. Of course, I can still write a clear and simple mess.

It’d be nice if our IDEs were less damned text based. Maybe then we could have IDEs that give us a better, visual language to describe relationships between classes in. But it’s difficult to see how that would work, or how it would avoid degenerating into all the lousy CASE tools that already litter architects desks.

Ideally writing code would be more like reading code. We would be able to describe relationships natively, at a higher level than naming methods and classes. But what does that even mean?! How can I describe a set of classes without scribbling boxes and arrows? And more importantly, how do I make that a part of the implementation language so it never gets out of sync?

Enterprise class code

There’s a natural instinct to assume that everybody else’s code is an untidy, undisciplined mess. But, if we look objectively, some people genuinely are able to write well crafted code. Recently, I’ve come across a different approach to clean code that is unlike the code I’ve spent most of my career working with (and writing).

Enterprise-class Code

There’s a common way of writing code, perhaps particularly common in Java, but happens in C#, too – that encourages the developer to write as many classes as possible. In large enterprises this way of building code is endemic. To paraphrase: every problem in an enterprise code base can be solved by the addition of another class, except too many classes.

Why does this way of writing code happen? Is it a reaction to too much complexity? There is a certain logic in writing a small class that can be easily tested in isolation. But when everyone takes this approach, you end up with millions of classes. Trying to figure out how to break up complex systems is hard, but if we don’t and just keep on adding more classes we’re making the problem worse not better.

However, it goes deeper than that. Many people (myself included, until recently) think the best way to write well-crafted, maintainable code is to write lots of small classes. After all, a simple class is easy to explain and is more likely to have a single responsibility. But how do you go about explaining a system consisting of a hundred classes to a new developer? I bet you end up scribbling on a whiteboard with boxes and lines everywhere. I’m sure your design is simple and elegant, but when I have to get my head around 100 classes just to know what the landscape looks like – it’s going to take me a little while to understand it. Scale that up to an enterprise with thousands upon thousands of classes and it gets really complex: your average developer may never understand it.

An Example

Perhaps an example would help? Imagine I’m working on some trading middleware. We receive messages representing trades that we need to store and pass on to systems further down the line. Right now we receive these trades in a CSV feed. I start by creating a TradeMessage class.

TradeMessage

private long id;

private Date timestamp;

private BigDecimal amount;

private TradeType type;

private Asset asset;

I’m a good little functional developer so this class is immutable. Now I have two choices: i) I write a big constructor that takes a hundred parameters or ii) I create a builder to bring some sanity to the exercise. I go for option ii).

TradeMessageBuilder


public TradeMessageBuilder onDate(Date timestamp)

public TradeMessageBuilder forAmount(BigDecimal amount)

public TradeMessageBuilder ofType(TradeType type)

public TradeMessageBuilder inAsset(Asset asset)

public TradeMessage build()

Now I have a builder from which I can create TradeMessage classes. However, the builder requires the strings to have been parsed into dates, decimals etc. I also need to worry about looking up Assets, since the TradeMessage uses the Asset class, but the incoming message only has the name of the asset.

We now test-drive outside-in like good little GOOS developers. We start from a CSVTradeMessageParser (I’m ignoring the networking or whatever else feeds our parser).

We need to parse a single line of CSV, split it into its component parts from which we’ll build the TradeMessage. Now we have a few things we need to do first:

  • Parse the timestamp
  • Parse the amount
  • Parse the trade type
  • Lookup the asset in the database

Now in the most extreme enterprise-y madness, we could write one class for each of those “responsibilities”. However, that’s plainly ridiculous in this case (although add in error handling or some attempts at code reuse and you’d be amazed how quickly all those extra classes start to look like a good idea).

Instead, the only extra concern we really have here is the asset lookup. The date, amount and type parsing I can add to the parser class itself – it’s all about the single responsibility of parsing the message so it makes sense.

CSVTradeMessageParser


public TradeMessage parse(String csvline)

private Date parseTimestamp(String timestamp)

private BigDecimal parseAmount(String amount)

private TradeType parseType(String amount)

Now – there’s an issue test driving this class – how do I test all these private methods? I could make them package visible and put my tests in the same package, but that’s nasty. Or I’m forced to test from the public method, mock the builder and verify the correctly parsed values are passed to the builder. This isn’t ideal as I can’t test each parse method in isolation. Suddenly making them separate classes seems like a better idea…

Finally I need to create an AssetRepository:

AssetRepository


public Asset lookupByName(String name)

The parser uses this and passes the retrieved Asset to the TradeMessageBuilder.

And we’re done! Simple, no? So, if I’ve test driven this with interfaces for my mocked dependencies, how many classes have I had to write?

  • TradeMessage
  • TradeType
  • TradeMessageBuilder
  • ITradeMessageBuilder
  • CSVTradeMessageParser
  • Asset
  • AssetRepository
  • IAssetRepository
  • TradeMessageBuilderTest
  • CSVTradeMessageParserTest
  • AssetRepositoryTest

Oh, and since this is only unit tests, I probably need some end-to-end tests to check the whole shooting match works together:

  • CSVTradeMessageParserIntegrationTest

12 classes! Mmm enterprise-y. This is just a toy example. In the real world, we’d have FactoryFactories and BuilderVisitors to really add to the mess.

Another Way

Is there another way? Well, let’s consider TradeMessage is an API that I want human beings to use. What are the important things about this API?

TradeMessage


public Date getTimestamp()

public BigDecimal getAmount()

public TradeType getType()

public Asset getAsset()

public void parse(String csvline)

That’s really all callers care about – getting values and parsing from CSV. That’s enough for me to use in tests and production code. Here we’ve created a nice, clean, simple API that is dead easy to explain. No need for a whiteboard, or boxes and lines and long protracted explanations.

But what about our parse() method? Hasn’t this become too complex? Afterall it has to decompose the string, parse dates, amounts and trade types. That’s a lot of responsibilities for one method. But how bad does it actually look? Here’s mine, in full:

public void parse(String csvline) throws ParseException
{
    String[] parts = csvline.split(",");

    setTimestamp(fmt.parse(parts[0]));
    setTradeType(TradeType.valueOf(parts[1]));
    setAmount(new BigDecimal(parts[2]));
    setAsset(Asset.withName(parts[3]));
}

Now of course, by the time you’ve added in some real world complexity and better error handling it’s probably going to be more like 20 lines.

But, let me ask you which would you rather have: 12 tiny classes, or 4 small classes? Is it better for complex operations to be smeared across dozens of classes, or nicely fenced into a single method?

Effectiveness of Teams

Agile places an emphasis on the importance of the team. The team make the decisions: what do we work on today, how do we tackle our constraints, even who should be in the group. But yet some research seems to suggest that individuals are more effective than teams.

For example in “59 seconds” Richard Wiseman questions the effectiveness of brainstorming – groups tend to focus on mundane, easily agreed upon suggestions; or be swayed by uncreative, charismatic team members.

How do we reconcile this conflict? If groups tend to lack creativity and flexibility in their thinking, why do agile teams appear to be more creative, more flexible and above all more effective? Is it an illusion, or does agile actually help teams achieve more?

Just one developer?

The trouble with software is its rarely a lone sport anymore. There aren’t many fields where one developer on his own can make a significant contribution. But where one developer can make meaningful progress you will get the best bang for buck. As soon as you add a second team member you need much more communication (ok, I might sit and talk to myself sometimes, but I talk much more when there’s another human being there). By the time you’re adding a third, fourth or fifth developer, you’re spending loads of time just talking and drawing on whiteboards and standing around having meetings.

If I’m the only person to have touched the code, when it crashes – I know exactly whose fault it is. As soon as there are more developers, we get to play blamestorming. “Well it works fine on my PC”, “It worked last time I ran it”, “You checked in last – it must be your bug”. You start to get the diffusion of responsibility that Wiseman talks about. People don’t feel personally responsible for the output, so they don’t feel compelled to make it better: half assed is good enough, it’s not my problem.

The truth is most activities of any size nowadays require a team of people to work on, which immediately raises the question of who works on what, when.

Fluidity

Maybe agile helps teams be more effective by letting the team be more fluid. Rather than the smartest people getting stuck on one problem or in one area, the fluidity and constant reassessment of agile allows the smart people to automatically refocus to where they need to be. But critically, it doesn’t need someone to micromanage the situation and tell them to work on the most important things – people will “self-organise” and naturally gravitate to where they can help most.

At the daily standup Harry says:

Jim – are you doing ok with the checkout flow? You’ve never done anything like that before so would it help if I came and paired with you today? The order history page can wait until next week so we can hit our target for Friday.

Magic: a “self-organising team”. Imagine some asshat manager had said that! Jim would feel like an idiot, Harry gets to feel awkward so tries not to ride roughshod over Jim’s work – both get dragged down and demotivated; the end result is slow, sloppy work and a miserable team. Instead, because the team came up with the idea, everyone’s happy about it and the work gets done as quickly as possible.

Because different people are always offering help – either because they’re nosy and want to know how something works, or because they’re some smartass know-it-all that’s good at everything – the fact that the smartest people are quickly rotating round the group’s biggest problems isn’t always plain to see. Everyone is moving around; but most of the movement is noise: the important thing is that the brightest, most capable people are moving to where they are needed most.

Maybe the fluidity simply creates a socially acceptable way for the smart people on the team to leap from problem to problem without the rest of the team feeling stupid.

Who’s the rockstar?

I hate the term, but if agile teams are more effective because the “rockstar” developers are working on all the important stuff – that suggests everyone else is working on the unimportant stuff. Now, if your company has time to pay idiots to work on stuff that nobody wants – maybe I can offer you some overpriced consultancy?

But that doesn’t happen, does it? Perhaps because the “rockstar” on the team, is probably only good at playing guitar (stretching the tortured analogy). I’ve heard him play a drum solo: it’s shit. But the drummer? Yeah, he’s not too bad at that. Everyone on a team has different strengths, and will do best at certain tasks. As a manager, it’s almost impossible to try and assign people to tasks to get the best out of everyone and deliver the most value possible. You’re basically trying to allocate resources centrally, which turns out to be pretty hard.

Instead by delegating resource allocation to the team, the team decide who would be best on each activity; the team take responsibility for delivering as much value as quickly as possible. Even if that sometimes means people are working on tasks they’re not suited for – those who are better at it might be working on something more valuable. Sometimes you need a drummer, even if they’re not the best drummer in the band.

Costs

Regular task switching and lots of pairing is great for creating an environment where developers can move from task to task easily. But this comes with a cost – I can’t immediately pick up where James left off, I need to talk to him to find out what he was doing and where he got to, I need to learn and understand the code he wrote yesterday before I can write more. This has a cost to it.

What about the diffusion of responsibility? If six different people all work on the same feature, won’t we find that nobody really cares whether it works, because everyone blames the other guys? Well, assuming we’re all professional developers, I’m sure we wouldn’t sink to such childish behaviour. But it’s surprising how easy you can become detached from the goal you’re aiming for – the overall benefit you’re trying to deliver for the customer. You know what’s left to do, so you do your little bit. You don’t think about the overall goal and what the customer actually wanted. You take your eye off of quality for a split second and bang! You screwed up.

I suspect diffusion of responsibility is a genuine problem in agile teams – which is why shared ownership is emphasised. We all own this code – so treat it as your own. In another light, it’s the craftsmanship ethic – to leave the code a little better than you found it. Don’t just assume the other guy knew what he was doing: fix it, properly. Without this, the diffusion of responsibility would lead to chaos.

To tolerate all these costs: task switching, diffused responsibility, communication and coordination overhead – there simply must be a massive benefit. The upside of having the right people on the right task at the right time must outweigh all those downsides.

But does it always? Does it on your team?

Testing asynchronous applications with WebDriverWait

Want to learn more about WebDriver? What do you want to know?

If you’re testing a web application, you can’t go far wrong with Selenium WebDriver. But in this web 2.0 world of ajax-y goodness, it can be a pain dealing with the asynchronous nature of modern sites. Back when all we had was web 1.0 you clicked a button and eventually you got a new page, or if you were unlucky: an error message. But now when you click links all sorts of funky things happen – some of which happen faster than others. From the user’s perspective this creates a great UI. But if you’re trying to automate testing this you can get all sorts of horrible race conditions.

Thread.sleep

The naive approach is to write your tests the same way you did before: you click buttons and assert that what you expected to happen actually happened. For the most part, this works. Sites are normally fast enough, even in a continuous integration environment, that by the time the test harness looks for a change it’s already happened.

But then… things slow down a little and you start getting flickers – tests that sometimes pass and sometimes fail. So you add a little delay. Just 500 milliseconds should do it, while you wait for the server to respond and update the page. Then a month later it’s flickering again, so you make it 1 second. Then two… then twenty.

The trouble is, each test runs at the pace that it runs at its slowest. If login normally takes 0.1 seconds, but sometimes takes 10 seconds when the environment’s overloaded – the test has to wait for 10 seconds so as not to flicker. This means even though the app often runs faster,  the test has to wait just in case.

Before you know it, your tests are crawling and take hours to run – you’ve lost your fast feedback loop and developers no longer trust the tests.

An Example

Thankfully WebDriver has a solution to this. It allows you to wait for some condition to pass, so you can use it to control the pace of your tests. To demonstrate this, I’ve created a simple web application with a login form – the source is available on github. The login takes a stupid amount of time, so the tests need to react to this so as not to introduce arbitrary waits.

The application is very simple – a username and password field with an authenticate button that makes an ajax request to log the user in. If the login is successful, we update the screen to let the user know.

The first thing is to write our test (obviously in the real world we’d have written the test before our production code, but its the test that’s interesting here not what we’re testing – so we’ll do it in the wrong order just this once):

@Test
public void authenticatesUser()
{
    driver.get("http://localhost:8080/");

    LoginPage loginPage = LoginPage.open(driver);
    loginPage.setUsername("admin");
    loginPage.setPassword("password");
    loginPage.clickAuthenticate();
    Assert.assertEquals("Logged in as admin", loginPage.welcomeMessage());
}

We have a page object that encapsulates the login functionality. We provide the username & password then click authenticate. Finally we check that the page has updated with the user message. But how have we dealt with the asynchronous nature of this application?

WebDriverWait

Through the magic of WebDriverWait we can wait for a function to return true before we continue:

public void clickAuthenticate() {
    this.authenticateButton.click();
    new WebDriverWait(driver, 30).until(accountPanelIsVisible());
}

private Predicate<WebDriver> accountPanelIsVisible() {
    return new Predicate<WebDriver>() {
        @Override public boolean apply(WebDriver driver) {
            return isAccountPanelVisible();
        }
    };
}
private boolean isAccountPanelVisible() {
    return accountPanel.isDisplayed();
}

Our clickAuthenticate method clicks the button then instructs WebDriver to wait for our condition to pass. The condition is defined via a predicate (c’mon Java where’s the closures?). The predicate is simply a method that will run to determine whether or not the condition is true yet. In this case, we delegate to the isAccountPanelVisible method on the page object. This does exactly what it says on the tin, it uses the page element to check whether it’s visible yet. Simple, no?

In this way we can define a condition we want to be true before we continue. In this case, the exit condition of the clickAuthenticate method is that the asynchronous authentication process has completed. This means that tests don’t need to worry about the internal mechanics of the page – about whether the operation is asynchronous or not. The test merely specifies what to test, the page object encapsulates how to do it.

Javascript

It’s all well and good waiting for elements to be visible or certain text to be present, but sometimes we might want more subtle control. A good approach is to update Javascript state when an action has finished. This means that tests can inspect javascript variables to determine whether something has completed or not – allowing very clear and simple coordination between production code and test.

Continuing with our login example, instead of relying on a <div> becoming visible, we could instead have set a Javascript variable. The code in fact does both, so we can have two tests. The second looks as follows:

public void authenticate() {
    this.authenticateButton.click();
    new WebDriverWait(driver, 30).until(authenticated());
}

private Predicate<WebDriver> authenticated() {
    return new Predicate<WebDriver>() {
        @Override public boolean apply(WebDriver driver) {
            return isAuthenticated();
        }
    };
}

private boolean isAuthenticated() {
    return (Boolean) executor().executeScript("return authenticated;");
}
private JavascriptExecutor executor() {
    return (JavascriptExecutor) driver;
}

This example follows the same basic pattern as the test before, but we use a different predicate. Instead of checking whether an element is visible or not, we instead get the status of a Javascript variable. We can do this because each WebDriver also implements the JavascriptExecutor allowing us to run Javascript inside the browser within the context of the test. I.e. the script “return authenticated” runs within the browser, but the result is returned to our test. We simply inspect the state of a variable, which is false initially and set to true once the authentication process has finished.

This allows us to closely coordinate our production and test code without the risk of flickering tests because of race conditions.