Element Objects: How to design acceptance tests to run against multiple UIs
updated almost 5 years ago; latest suggestion almost 5 years ago
Responsive and native application support is becoming critical to the success of an application. Are you testing these important parts of your application with the same rigor that you test the full sized web application?
One approach to providing this coverage is to write multiple test suites. This can lead to maintenance overhead and missing tests due to the overlap in the various test suites. I propose you can dry up your test suites and write a single, robust, and readable suite that exercises multiple interfaces.
In this talk, I will present the Element Object pattern, derived from the Page Object pattern. This pattern gives you the tool to write one acceptance test suite that captures the behavior of your application and runs each test against multiple interfaces. Element Objects allow you to write your tests in a way that is decoupled from the implementation of your interface. Instead, each test captures the behavior of your application and is run multiple times, dynamically plugging in the interface specific code to achieve the goal of the test. To achieve this, you abstract your tests from implementation at the Interface level (browser/application), Page level (registration page), and Element level (flash message).
This approach also leads to benefits. You get a more readable acceptance test suite that tests multiple UI types. You get re-use out of your Page and Element Objects. A flash message exists in multiple places and testing it's behavior should be the same code. It also allows you to iterate faster on different UIs. You have the test that captures the behavior, you just need to plug in the implementation for the different interface.
In this talk I'll show a working example of this using capybara, rspec, and rails. This idea came out of the pain of testing large rails applications. I leverage several features of ruby, rspec and capybara to accomplish the pattern.
Yes, there is more complexity, but if you're testing (or not testing) multiple UIs, you already have it. I'm not advocating this pattern for straightforward, single UI applications; more trying to give developers another tool in their toolbox.
It can definitely turn into object soup, so you must be conscious on how far you take it. Patterns are more of a heuristic or a starting point, and don't apply generally. It's important to know the cons to this pattern (complexity being a big one) along side the pros.
I've been working with responsive design with this pattern. I'm exploring how to integrate something like "testing with frank" or iOS selenium to drive an actual iOS app (or safari for proof of concept).
I hope this talk sparks conversation into future testing patterns as ruby/rails applications grow and get more complicated.
I think it would be useful to mention which "native" platforms you've been working with.
I'd like to hear about this. I'm not familiar with the Element Object pattern. It sounds like you'd be introducing a fair few extra levels of abstraction on top of the typical Ruby test suite and potentially quite a bit of glue. Is it ever hard to keep all the plates spinning?
Sounds good to me. I suggest you tweak the proposal slightly to include that information (most people won't bother reading these comments) so that it's more obvious what the meat of the talk will contain.
Yeah, definitely. You're right in that this talk is a general pattern that can be used with any language.
I have a working example of this using capybara, rspec, and rails. This idea came out of the pain of testing large rails applications. I leverage several features of ruby, rspec and capybara to accomplish the pattern.
There is definitely places for code examples in this talk. For example: what a typical capybara spec looks like and how it looks after implementing this pattern.
This sounds interesting, but is there any way to make it more concrete? I'm sure the technique can be applied with any testing framework (and in any language), but can you be specific about what framework you're going to be showing this in?
Will you be using something like RSpec or Cucumber? Are Capybara or Webrat involved? Selenium? These decisions are probably orthogonal to the subject of the talk, but concrete details about what you're going to do in the talk, and what we're going to see, make it easier to imagine what it will be like.