The TestProject framework provides support for running TestProject tests and actions on a local development environment, and this blog post explains how we can use this feature.
After we have finished this blog post, we:
- Know how we can obtain our developer key.
- Understand how we can pass input parameter values to the invoked test case.
- Know how we can write a runner class that runs a TestProject test on our local development environment.
Let's start by finding out how we can run a TestProject test on our local development environment.
This blog post assumes that:
- You are familiar with TestProject
- You can package TestProject tests and addons with Gradle
- You can write tests with TestProject
- You can write custom TestProject addons
- You can input and output parameters to TestProject actions
- You can use TestProject actions in your test classes
By the way, you might want to read the other parts of my TestProject tutorial.
Implementing a Runner Class
If we want to run a TestProject test on our local development environment, we have to implement a runner class that runs our test. During this tutorial we will write a runner class that runs a TestProject test which we wrote in an earlier part of my TestProject tutorial. This test ensures that the search result page of my blog displays at least one result after we have submitted the search form.
We can implement this runner class by following these steps:
First, we have to obtain our developer key from the app.testproject.io website. We can get our developer key by following these steps:
- Log in to the app.testproject.io website.
- Open the 'Developers' page.
- Click the 'Developer Key' button. This button opens a modal dialog that displays our developer key.
The following figure illustrates the layout of the 'Developers' page:
Second, because we want to run a TestProject test that has input parameters, we have to figure out a way to pass the parameter values to the invoked test. Because the parameters fields are private
, we have to add two setters methods to our test class. These methods set the values of the searchPageUrl
and searchTerm
fields.
After we have added these setter methods to our test class, its source code looks as follows:
import io.testproject.java.annotations.v2.Parameter; import io.testproject.java.annotations.v2.Test; import io.testproject.java.sdk.v2.drivers.WebDriver; import io.testproject.java.sdk.v2.enums.ExecutionResult; import io.testproject.java.sdk.v2.exceptions.FailureException; import io.testproject.java.sdk.v2.tests.WebTest; import io.testproject.java.sdk.v2.tests.helpers.WebTestHelper; import io.testproject.proxy.addon.BlogSearchAddon; import io.testproject.proxy.addon.net.petrikainulainen.testproject.addon.BlogSearchAction; import io.testproject.proxy.addon.net.petrikainulainen.testproject.addon.BlogSearchResultFinderAction; import io.testproject.proxy.addon.net.petrikainulainen.testproject.addon.ClearBlogSearchFieldAction; @Test( name = "The search result page must display least one search result", description = "Verifies that the search result page displays at least one search result" ) public class BlogSearchResultCountTest implements WebTest { @Parameter(description = "Contains the url of the search page") private String searchPageUrl; @Parameter(description = "Contains the submitted search term") private String searchTerm; @Override public ExecutionResult execute(WebTestHelper webTestHelper) throws FailureException { WebDriver browser = webTestHelper.getDriver(); browser.get(searchPageUrl); ActionRunner actionRunner = new ActionRunner(webTestHelper); ClearBlogSearchFieldAction clearSearchField = BlogSearchAddon .getClearBlogSearchFieldAction(); actionRunner.runAction(clearSearchField); BlogSearchAction blogSearch = BlogSearchAddon.blogSearchAction(searchTerm); actionRunner.runAction(blogSearch); BlogSearchResultFinderAction searchResults = BlogSearchAddon .getBlogSearchResultFinderAction(); actionRunner.runAction(searchResults); return searchResults.actualSearchResultCount > 0 ? ExecutionResult.PASSED : ExecutionResult.FAILED; } public void setSearchPageUrl(String searchPageUrl) { this.searchPageUrl = searchPageUrl; } public void setSearchTerm(String searchTerm) { this.searchTerm = searchTerm; } }
Third, we have to create a public
runner class that runs our test. After we have created our runner class, its source code looks as follows:
public class BlogSearchResultCountTestRunner { }
Fourth, we have to add four constants to our runner class:
- The
BROWSER
constant configures the browser that runs our test. Because we want to run our test by using the Chrome web browser, we have to set the value of this constant toAutomatedBrowserType.Chrome
. - The
DEVELOPER_KEY
constant configures our developer key. - The
SEARCH_PAGE
constant configures the url of the web page that renders the search form. - The
SEARCH_TERM
constant configures the used search term.
After we have added these constants to our runner class, its source code looks as follows:
public class BlogSearchResultCountTestRunner { private static final AutomatedBrowserType BROWSER = AutomatedBrowserType.Chrome; private static final String DEVELOPER_KEY = "PUT_YOUR_DEVELOPER_KEY_HERE"; private static final String SEARCH_PAGE = "https://www.petrikainulainen.net/blog"; private static final String SEARCH_TERM = "junit 5"; }
AutomatedBrowserType
enum specifies all web browsers which are supported by the TestProject framework.
Fifth, we have to add a public
and static
main()
method to our runner class. This method takes a String
array as a method parameter and doesn't return anything. Also, this method can throw an Exception
.
After we have added the main()
method to our runner class, its source code looks as follows:
public class BlogSearchResultCountTestRunner { private static final AutomatedBrowserType BROWSER = AutomatedBrowserType.Chrome; private static final String DEVELOPER_KEY = "PUT_YOUR_DEVELOPER_KEY_HERE"; private static final String SEARCH_PAGE = "https://www.petrikainulainen.net/blog"; private static final String SEARCH_TERM = "junit 5"; public static void main(String[] args) throws Exception { } }
Sixth, we have to implement the main()
method by following these steps:
- Create a
Runner
object that can run web tests. We can create this object by invoking thecreateWeb()
method of theRunner
class. When we invoke this method, we have to specify our developer key and the web browser that runs our test. - Create a new
BlogSearchResultCountTest
object. - Configure the URL of the search page and the used search term.
- Run our test by invoking the
run()
method of theRunner
class. Remember to pass the invoked test object as a method parameter.
After we have implemented the main()
method, the source code of our runner class looks as follows:
import io.testproject.java.enums.AutomatedBrowserType; import io.testproject.java.sdk.v2.Runner; public class BlogSearchResultCountTestRunner { private static final AutomatedBrowserType BROWSER = AutomatedBrowserType.Chrome; private static final String DEVELOPER_KEY = "PUT_YOUR_DEVELOPER_KEY_HERE"; private static final String SEARCH_PAGE = "https://www.petrikainulainen.net/blog"; private static final String SEARCH_TERM = "junit 5"; public static void main(String[] args) throws Exception { Runner runner = Runner.createWeb(DEVELOPER_KEY, BROWSER); BlogSearchResultCountTest test = new BlogSearchResultCountTest(); test.setSearchPageUrl(SEARCH_PAGE); test.setSearchTerm(SEARCH_TERM); runner.run(test); } }
However, it's possible to run our TestProject tests with JUnit 4 or 5. If we want to use this approach, we have to follow these two rules:
- We should create the
Runner
object in a setup method that's invoked once before a test method is run. - We should write a test method that runs our TestProject test. If we want to run multiple TestProject tests, we should write one test method per an invoked TestProject test.
Finally, even though our runner class runs a TestProject test, we can use the same approach for running TestProject actions as well.
We have now written a runner class that runs our TestProject test on our local development environment. When we want to run our TestProject test, we have to start our TestProject agent and run the main()
method of the BlogSearchResultCountTestRunner
class. Next, we will find out how this runner class helps us to debug the invoked test case.
Debugging the Invoked TestProject Test
After we have implemented our runner class, we can debug our TestProject test by following these steps:
First, we have to open the test class and put a breakpoint to the preferred line. For example, if we want to stop the execution of our test case before we make the assertion which ensures that the search result page has at least one search result, we must open our test class and put our breakpoint to the line 45.
The following figure illustrates this step:
Second, we have to run our runner class (BlogSearchResultCountTestRunner
) in a debug mode. When we do this, our IDE should stop the execution of the invoked TestProject test when the execution reaches the line that has a breakpoint (45). When the execution is stopped, we can take a look at the browser window and (hopefully) see why the test case fails.
The following figure demonstrates what we should see when our IDE stops the execution of the BlogSearchResultCountTest
class:
We have now written a runner class that runs a TestProject test on our local development environment, and we understand how this runner class helps us to debug a failing test case. Let's summarize what we learned from this blog post.
Summary
This blog post has taught us four things:
- Before we can run TestProject tests (or actions) on our local development enviroment, we have to obtain our developer key from the app.testproject.io website.
- When we want to run a TestProject test (or an action) on our local development environment, we have to write a special runner class that runs our test.
- We can run TestProject tests and actions by using the
Runner
class. - We can debug the invoked TestProject test (or action) by using the debugger of our IDE.
P.S. You can get the example application of this blog post from Github.