2

There‘s an approach in unit testing where, instead of just writing the technical details in every test method, you create a library of helper functions like

  • givenServiceFails (that acts on mock behavior)
  • whenUserDataIsRequested (acting on the production code) and
  • thenDataIsDisplayed (asserting mocks or production code)

Instead of having all the implementation details in the test methods, you call those helper methods that contain the implementation details.

Please note, this is not about BDD. BDD is not a test framework, it's a communication framework for tech and business people that results in runnable specification (Gherkin).

It only shares certain benefits with Gherkin-Libraries like Cucumber. E.g.:

  • It has the benefit that you can reuse those helper methods in multiple test methods
  • It adds a layer of abstraction over the production code that makes the test business easier to understand
  • As the test methods are decoupled from the implementation details (interaction with production code, mocks and assertions), those implementation details becomes easier to change (maintainability).

How do you call that approach to abstract the business of the test from the implementation details? A natural naming for that approach for me would be „testing API“, but it‘s too similar to „test API“, which is a mock implementation of a „real“ API. The best I could guess would be "test abstraction layer" or the like.

My aim is to find references to that approach so I can correctly outline pros and cons of it and finally write about it. If I don't have the proper name for the approach, it's hard to engage in communication about it.

15
  • 1
    This is not something I would consider to be useful for unit tests, although I might have a different definition. To me, a unit test is not something that requires a database, file system, Web service, or anything else outside of the thread running the test. Commented Mar 24 at 0:01
  • 2
    I think this is how BDD was originally intended to be done. Before it got hijacked for end-to-end Cucumber tests.
    – Euphoric
    Commented Mar 24 at 6:03
  • 1
    This is just ordinary refactoring. Commented Mar 24 at 9:58
  • 1
    dunno how this gets closed for "opinion based" when I find two sensible seeming answers and @basilevs finds an exact match all with links
    – Ewan
    Commented Mar 25 at 9:16
  • 2
    The problem with questions about "naming things" is that there is no canonical, authoritative list of names. As a result, people tend to shout out a bunch of ideas, all of which could be equally correct. As a result, it becomes a list of opinionated answers with no reference to anything official, and no consensus on which name best fits. Occasionally there is a canonical name. These questions are hit-or-miss, because most things don't have an agreed-upon name, and therefore the question is opinion-based. Not a bad question, though. Just not a good fit for the Q&A style of this community. Commented Mar 25 at 12:48

2 Answers 2

0

I think the approach you outline comes from BDD/Gherkin style testing.

When you write your BDD tests in plain language..

Given the home page is loaded
When the user clicks on login
Then A login form is displayed

You then have to actually write code to implement those steps and tests. Invariably you end up with methods which match the language of the tests

LoadHomePage()
ClickLogin()
AssertLoginFormDisplayed()

Given that BDD lends it's to reuse of the steps, these methods also see lots of reuse across your tests.

There is another pattern in unit testing called ObjectMother which you might be thinking of.

This is Where you apply similar techniques to your test data eg

var target = TestData.Pages.HomePage().WhenNotLoggedIn();

or maybe even

var target = TestData.Pages.HomePage().WhenNotLoggedIn();
target.ClickLogin();

depending on how far you want to take it.

6
  • 1
    "This is where you apply similar techniques to your test data" - I just wanted to add (or clarify), it's not necessarily plain data classes (though that's probably very common), Object Mother could also produce a preconfigured object that implements some behavior, or a preconfugured (or partially configured) mock. Commented Mar 24 at 21:30
  • if you read to the end you will see i give an example where methods are called
    – Ewan
    Commented Mar 25 at 9:19
  • I agree there are similarities, but I'm looking for the umbrella term. I updated my question to make it more clear what I meant. Sorry if I didn't put it clear enough.
    – nepa
    Commented Mar 25 at 12:15
  • I think the PageObject pattern is a correct answer, seems to match everything you describe
    – Ewan
    Commented Mar 25 at 12:40
  • "if you read to the end ..." - that's true. Don't get me wrong, I think it's a good answer (got a +1 from me), just wanted to explicitly mention this for the benefit of any readers who might be less experienced. Also I was thinking of a slightly different situation - e.g, the obtained object might be a dependency to the instance under test (or a parameter to the method being tested), so the behavior I'm talking about might entirely play out within the call made in "act" step (that is, in the top level test code, there may be no methods called on the obtained instance prior to it being used). Commented Mar 25 at 23:37
-1

This is PageObject pattern.

The idea is to wrap an object under test in an utility layer useful for testing.

The object under test can be domain object, a web page, database, UI dialog, anything. The name is a bit misleading as it is applied outside of webdev, to small controls, to whole applications, not only to web pages.

Usually PageObject operates on a higher abstraction level then than underlying object - it turns clicks into navigation, DB results into lists, dialogs with multiple inputs into methods with multiple arguments, multiple operations into scenarios, etc.

12
  • 1
    I won't downvote, but this is not the PageObject pattern (which is a similar idea, but it's at a slightly lower lever compared to what the OP is asking about, and the motivation is different). Also, the name doesn't make sense in the context the OP is describing (even given your disclaimer). Commented Mar 24 at 21:24
  • 1
    really? I thought this was spot on??
    – Ewan
    Commented Mar 25 at 9:11
  • 1
    It's not the page object pattern because the function that calls whenUserDataIsRequested and thenDataIsDisplayed doesn't need to know what pages the requests and displays are done on, or even if they are on pages. They could be on a CLI interface, or if we stretch the meaning of Displayed a conversational interface (e.g. Alexa skill or chatbot), without any need to change the code in the actual test file.
    – bdsl
    Commented Mar 25 at 13:10
  • 1
    @Ewan I don't think it's quite the same. Fowler writes "... have an album list page object containing several album page objects. There would probably also be a header page object and a footer page object." . Implying that the code depending on page objects needs to be aware of the existence of headers, footers and album list pages containing album pages. I think the pattern the OP is asking about is one where even that information is abstracted away.
    – bdsl
    Commented Mar 25 at 13:27
  • 1
    That is abstraction though? also the very next line: "That said, some of the hierarchy of a complex UI is only there in order to structure the UI - such composite structures shouldn't be revealed by the page objects. The rule of thumb is to model the structure in the page that makes sense to the user of the application."
    – Ewan
    Commented Mar 25 at 13:30

Not the answer you're looking for? Browse other questions tagged or ask your own question.