<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.9.3">Jekyll</generator><link href="https://concordion.org/feed.xml" rel="self" type="application/atom+xml" /><link href="https://concordion.org/" rel="alternate" type="text/html" /><updated>2023-07-16T10:18:59+00:00</updated><id>https://concordion.org/feed.xml</id><title type="html">Specification by Example | Concordion</title><subtitle>Concordion website</subtitle><entry><title type="html">Concordion | Runners and Drivers</title><link href="https://concordion.org/blog/runners-drivers" rel="alternate" type="text/html" title="Concordion | Runners and Drivers" /><published>2017-11-18T00:00:00+00:00</published><updated>2017-11-18T00:00:00+00:00</updated><id>https://concordion.org/blog/runners-drivers</id><content type="html" xml:base="https://concordion.org/blog/runners-drivers">&lt;p&gt;This article describes the Runners and Drivers pattern which enables test code to be layered with clean interfaces. This enhances maintainability of the code and leads to effective reuse of the application drivers across test suites. In addition, it opens up the drivers for use in exploratory and maintenance scripting. It also avoids lock-in to any specific test runner or driver, opening up the potential for future migration to new test runners or drivers.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/runners-drivers.png&quot; alt=&quot;Visual representation of Layering test code with Runners and Drivers&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;application-drivers&quot;&gt;Application Drivers&lt;/h2&gt;
&lt;p&gt;An Application Driver is responsible for manipulating an application through one of its interfaces (eg. web app, web service, database, desktop application, host, message queue).&lt;/p&gt;

&lt;p&gt;The Driver will normally require a 3rd party library to interface with the application, such as Selenium WebDriver. (In some cases, it is also possible to interface directly with the service layer of the application.)&lt;/p&gt;

&lt;p&gt;A basic driver may expose its functionality in terms of actions on the interface - eg. enter first name, click OK, get error message.&lt;/p&gt;

&lt;p&gt;It is often worthwhile to add functionality to group the actions into workflows that represents the business intent, eg. update payee details, make one-off payment.&lt;/p&gt;

&lt;p&gt;A common pattern used for Application Drivers is the &lt;a href=&quot;https://github.com/SeleniumHQ/selenium/wiki/PageObjects&quot;&gt;Page Object&lt;/a&gt; pattern. This encapsulates the logic for driving a page in one place so that it is simple to change, and provides an easy interface for users.  Example usage (using Groovy) might be:&lt;/p&gt;

&lt;div class=&quot;language-groovy highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;loginPage&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gotoLoginPage&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;landingPage&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;loginPage&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;loginAs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;user123&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;password&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;oneOffPaymentPage&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;landingPage&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;selectOneOffPayment&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;oneOffPaymentPage&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;pay&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;230.50&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;06-9952-5439870-01&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;It is good practice to break the test fixtures into separate Action and Page objects. The Action objects implement user actions, such as “Transfer money between accounts”. The Page objects abstract operations on the web page, for instance “Click on Transfer button”. The acceptance and automated tests should use the Action objects where possible, but may need to use the Page objects for some operations. The Page objects isolate the tester from changes to the web page (for example if the location or name of the Transfer button are changed). The Action objects isolate the tester from higher level changes, such as “Transfer money” being implemented using a different workflow or metaphor (eg drag and drop).&lt;/p&gt;

&lt;h2 id=&quot;runners&quot;&gt;Runners&lt;/h2&gt;
&lt;p&gt;Once you have implemented Application Drivers, they can be reused for a number of use cases, for example:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;running tests,&lt;/li&gt;
  &lt;li&gt;data setup,&lt;/li&gt;
  &lt;li&gt;scripting&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can use a wide variety of frameworks for running the tests, including basic xUnit style, Specification by Example (such as Concordion), data-driven, keyword-driven etc. These frameworks run the tests and report test results for the user.&lt;/p&gt;

&lt;p&gt;Data setup could be spreadsheet-driven, and could be one-off (eg. data migration) or part of a regular test setup.&lt;/p&gt;

&lt;p&gt;Scripting would use a language such as Groovy, VBScript, Python or Ruby to perform custom actions on the application. When performing exploratory testing, you can speed up repetitive actions (eg. logon and navigation) through scripting.&lt;/p&gt;

&lt;h2 id=&quot;advantages-of-using-runners-and-drivers&quot;&gt;Advantages of using Runners and Drivers&lt;/h2&gt;
&lt;p&gt;By separating drivers and runners, you achieve a high degree of reuse.&lt;/p&gt;

&lt;p&gt;It is important to never include test logic in the Application Drivers, otherwise your Driver becomes tied to the particular test runner framework that you are using. Similarly don’t expose driver specifics to the test layer - for example, you should return &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Strings&lt;/code&gt; or domain objects rather than return &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;WebElements&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;With the right level of abstraction, you minimise the changes required to test code when the application changes - with the goal of only needing one change to test code for each application change. As the organisation grows a library of drivers, you are able to capitalise upon the work of others to quickly create new tests.&lt;/p&gt;</content><author><name>Nigel Charman</name></author><summary type="html">This article describes the Runners and Drivers pattern which enables test code to be layered with clean interfaces. This enhances maintainability of the code and leads to effective reuse of the application drivers across test suites. In addition, it opens up the drivers for use in exploratory and maintenance scripting. It also avoids lock-in to any specific test runner or driver, opening up the potential for future migration to new test runners or drivers.</summary></entry><entry><title type="html">Concordion | .NET Presentation</title><link href="https://concordion.org/blog/concordion-net-presentation" rel="alternate" type="text/html" title="Concordion | .NET Presentation" /><published>2017-08-05T00:00:00+00:00</published><updated>2017-08-05T00:00:00+00:00</updated><id>https://concordion.org/blog/concordion-net-presentation</id><content type="html" xml:base="https://concordion.org/blog/concordion-net-presentation">&lt;p&gt;We’re keen to update Concordion.NET to match the Concordion 2.0 Java features.&lt;/p&gt;

&lt;p&gt;Here’s a presentation about Concordion.NET:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;/presentations/2017-07-Concordion.NET&quot;&gt;2017-07-Concordion.NET&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is released under a &lt;a href=&quot;https://creativecommons.org/licenses/by/4.0/&quot;&gt;Creative Commons Attribution 4.0 International license&lt;/a&gt;, so please feel free to adapt and share this for your own presentation. All we ask for is attribution.&lt;/p&gt;

&lt;p&gt;For those keen to contribute to Concordion 2.0, please join in the discussion &lt;a href=&quot;https://github.com/concordion/concordion.net/issues/15&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;</content><author><name>Nigel Charman</name></author><summary type="html">We’re keen to update Concordion.NET to match the Concordion 2.0 Java features.</summary></entry><entry><title type="html">Concordion | Presentations</title><link href="https://concordion.org/blog/presentations" rel="alternate" type="text/html" title="Concordion | Presentations" /><published>2017-06-10T00:00:00+00:00</published><updated>2017-06-10T00:00:00+00:00</updated><id>https://concordion.org/blog/presentations</id><content type="html" xml:base="https://concordion.org/blog/presentations">&lt;p&gt;I’ve been presenting Concordion at a few meetup groups and brown bag sessions recently. Here are the slide decks.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;/presentations/2017-04-Concordion-2.0&quot;&gt;2017-04-Concordion-2.0&lt;/a&gt; - mixed audience&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/presentations/2016-05-Concordion-2.0&quot;&gt;2016-05-Concordion-2.0&lt;/a&gt; - technical audience&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/presentations/2016-05-05_Wellington_Test_Automation_Meetup&quot;&gt;2016-05-05_Wellington_Test_Automation_Meetup&lt;/a&gt; - short, technical test audience&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These use the &lt;a href=&quot;https://github.com/hakimel/reveal.js/&quot;&gt;reveal.js&lt;/a&gt; presentation format.&lt;/p&gt;

&lt;p&gt;These are released under a &lt;a href=&quot;https://creativecommons.org/licenses/by/4.0/&quot;&gt;Creative Commons Attribution 4.0 International license&lt;/a&gt;, so please feel free to adapt and share these for your own presentations. All we ask for is attribution.&lt;/p&gt;</content><author><name>Nigel Charman</name></author><summary type="html">I’ve been presenting Concordion at a few meetup groups and brown bag sessions recently. Here are the slide decks.</summary></entry><entry><title type="html">Concordion | Writing a Blog</title><link href="https://concordion.org/blog/blog" rel="alternate" type="text/html" title="Concordion | Writing a Blog" /><published>2017-06-08T00:00:00+00:00</published><updated>2017-06-08T00:00:00+00:00</updated><id>https://concordion.org/blog/blog</id><content type="html" xml:base="https://concordion.org/blog/blog">&lt;h1 id=&quot;welcome&quot;&gt;Welcome!&lt;/h1&gt;

&lt;p&gt;Welcome to the Concordion community blog. The primary goal of this blog is to deliver interesting content about Concordion. 
If you have valuable ideas, tips, or experiences, then you are  more than welcome to contribute. Sharing practical examples are 
important. After reading your blog post, your readers should not only have gained new insights and ideas, but also know how to actually 
implement these in practice. The more practical your tips, techniques and ideas are, the better.&lt;/p&gt;

&lt;p&gt;This community blog uses &lt;a href=&quot;https://jekyllrb.com/&quot;&gt;Jekyll&lt;/a&gt; to allow blogging using simple 
static &lt;a href=&quot;https://daringfireball.net/projects/markdown/&quot;&gt;Markdown&lt;/a&gt; or HTML web pages, with all of the content hosted on the version 
control platform of GitHub. The goal was to eliminate the complexity of other blogging platforms by creating a workflow that allows you to 	
&lt;a href=&quot;http://tom.preston-werner.com/2008/11/17/blogging-like-a-hacker.html&quot;&gt;blog like a hacker&lt;/a&gt;. 
To create a new blog entry you shold get started with the following steps:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Create your own fork of the blog.&lt;/li&gt;
  &lt;li&gt;Copy the blog template and rename it according to the topic you want to write about.&lt;/li&gt;
  &lt;li&gt;Edit the header information and add your article content.&lt;/li&gt;
  &lt;li&gt;Check your blog post.&lt;/li&gt;
  &lt;li&gt;Create a pull request to get your article published.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;1-create-your-own-fork-of-the-blog&quot;&gt;1. Create your own fork of the blog&lt;/h2&gt;

&lt;p&gt;A &lt;strong&gt;fork&lt;/strong&gt; is a copy of the website repository containing all blog entries. 
Forking a repository allows you to freely experiment with changes without affecting the original project. 
You can accomplish this step directly in the browser. 
Go to &lt;a href=&quot;https://github.com/concordion/concordion-website/&quot;&gt;the blog repository on github.com&lt;/a&gt; and click on fork in the top-right 
corner of the page. 
That’s it! Now, you have your private copy of the original blog repository.&lt;/p&gt;

&lt;h2 id=&quot;2-rename-the-template-with-the-title-of-your-post&quot;&gt;2. Rename the template with the title of your post&lt;/h2&gt;

&lt;p&gt;To write a new blog post, you have to create a new Markdown or HTML file within the directory that contains all existing blog entries, 
&lt;a href=&quot;https://github.com/concordion/concordion-website/tree/gh-pages/_posts/&quot;&gt;_posts&lt;/a&gt;. 
To achieve this step:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;Navigate to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_posts&lt;/code&gt; directory of your fork of the blog that you have created in the previous step.&lt;/li&gt;
  &lt;li&gt;Click on the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Create new file&lt;/code&gt; button.&lt;/li&gt;
  &lt;li&gt;Set the file name to include today’s date and the title of your post. The naming convention requires posts to be named &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;yyyy-mm-dd-title.md&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;Copy the contents of one of the existing posts for further modification.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;3-write-your-blog-content&quot;&gt;3. Write your blog content&lt;/h2&gt;

&lt;p&gt;Now you can edit the content of your post file. First you should edit the &lt;a href=&quot;http://jekyllrb.com/docs/frontmatter/&quot;&gt;first few lines of the file containing metadata&lt;/a&gt; for your article. 
Please, provide a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;title&lt;/code&gt; that will appear in the title bar, along with a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;heading&lt;/code&gt; that will show at the top of the page, a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;description&lt;/code&gt; for the meta tag and for social media shares, and a unique &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;identifier&lt;/code&gt; that will be used for comments to the article.
Additionally, provide your name next to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;author&lt;/code&gt; tag, and optionally a link to your homepage with the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;homepage&lt;/code&gt; tag.
This will be displayed at the top of your blog post, similar to the information you see in this blog example.&lt;/p&gt;

&lt;p&gt;Please, describe your valuable tips, ideas, or experiences after the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;---&lt;/code&gt; at the end of the header.
You can either type your content using Markdown or HTML syntax directly in the browser or &lt;a href=&quot;https://help.github.com/articles/fork-a-repo/&quot;&gt;clone the fork of your blog onto your computer&lt;/a&gt; and use one of the available editors.&lt;/p&gt;

&lt;h2 id=&quot;4-check-your-blog-post&quot;&gt;4. Check your blog post&lt;/h2&gt;

&lt;p&gt;To run Jekyll locally, you will need &lt;a href=&quot;http://bundler.io/&quot;&gt;Ruby bundler&lt;/a&gt; installed. Then run:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bundle update&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bundle exec jekyll s&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Your blog will then be created under &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;http://localhost:4000/blog.html&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;5-publish-your-blog-post&quot;&gt;5. Publish your blog post&lt;/h2&gt;

&lt;p&gt;Your blog post is now written and looking good - you have just to publish it. This is done through issuing a &lt;a href=&quot;https://help.github.com/articles/about-pull-requests/&quot;&gt;pull request&lt;/a&gt; on github.com. 
Open the fork of the blog you have created in step 1 in your web browser. 
At the bottom of the page, select the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Create a new branch for this commit and start a pull request&lt;/code&gt; radio button. 
Give the pull request a descriptive name.
Add a short comment about the idea of your blog post and press the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Propose new file&lt;/code&gt; button. 
After the pull request has been accepted, you can &lt;a href=&quot;https://concordion.org/blog&quot;&gt;view your blog on the Concordion webpage&lt;/a&gt;.&lt;/p&gt;</content><author><name>Jacek Ratzinger</name></author><summary type="html">Welcome!</summary></entry></feed>