Now sometimes that user could be another developer, but in this case, the user is an end user. One thing I've found helpful is to imagine yourself talking with the user of the System Under Test.
#ANDTHEN ACTIX BLOCK CODE#
Now, this might seem trivial, but again its important to have all the code of your test at the same level of abstraction all the way through -Īnd find('button').trigger('click') is just not how you would tell a user to use your application. Well there's actually a test helper called click that we can use instead, like this click( 'button') Now before we leave, there's two more things we want to do.įirst, we're using the visit and fillIn helpers here, but then on line 5 we use find('button') and then we call trigger('click'). And we'll remove the container lookup here as well. Implementation details in tests are typically at the wrong levels of abstraction, and they make our tests brittle - so, even though session.get('isAuthenticated') is true, we want to remove this code from our test. Now, it's important to note that this session object's isAuthenticated property will still be true - we haven't changed that behavior - but this property on this service object is just an implementation detail the app as it currently stands, and this is not actually demonstrating that the app is functioning correctly from the perspective of the user assert.equal(find( '.title').text(), 'Your posts')) Instead of checking the value of a service, we'll assert against the rendered output of our application - let's say that in this application, when you successfully log in, you see a title rendered to the screen somewhere and it says "Your posts". So, we want to fix this test so that the assertion is at the same level of abstraction as our helper code. And that's the kind of behavior we want to capture in these acceptance tests. When you go to and log in, how do you know that you were able to successfully log in? Do you open the JavaScript console and start inspecting variables? Well no - you know you were able to log in because the home page rendered, you're able to see your tweets and so on.
The question we need to ask is, do our users care about a session service object - or any other Ember object for that matter? Well, no - they interact with our app by using a browser, a mouse and a keyboard, and seeing what's actually rendered to the screen. So, now we know this test should really be from the perspective of the end user - but we have this code that's dealing with the session service. The abstraction level of code in the test should match the abstraction level of the System Under Test.Īnd this is why the test helpers like visit and fillIn exist - again, these are more expressive of the behavior of the end-user, which is exactly what this test is trying to capture. So, for acceptance tests, the System Under Test is actually our application as a whole, and this is how we can know whether or not the code in our test is at the right level of abstraction. The idea behind System Under Test is that every test we write should be focused on verifying the behavior of some piece of our software, whether it's a function, a component, or something else. There's even a term for this: it's called System Under Test, which is sometimes abbreviated as SUT.
Now, "what it is we're trying to test" is of critical importance when it comes to identifying these abstraction layers. But fillIn is an abstraction around this low-level code that's designed from the perspective of a user actually using our app - and because of this we would say that fillIn is a more expressive way to represent what it is we're trying to test. This is pseudocode but you get the idea - this is lower-level because it's using these lower-level APIs to interact with our web app, in the same way that a programmer would in code. So what does that mean? Well let's take a look at a test.
So the idea here is that, all the code within our test suite is at a certain abstraction level, and it's up to us to ensure that any code within a single test is all at the same consistent level pf abstraction all the way through. Something that had a big impact on how I write tests was learning about levels of abstraction in testing.