After a PR is merged, your local branch can pile up and just start to stink. Make this gitclean.sh handy.
git branch | grep -v master | xargs git branch -D
git remote prune origin
Simplest steps to automate API & UI tests
After a PR is merged, your local branch can pile up and just start to stink. Make this gitclean.sh handy.
git branch | grep -v master | xargs git branch -D
git remote prune origin
Now I am going to add a new Rest API test to this framework.
Let’s visit this website: https://github.com/rest-assured/rest-assured/wiki/GettingStarted
Add the maven dependency to the pom.xml as the above page suggests. Now we can add a test.
package com.directly.potassium;
import org.testng.annotations.Test;
import static io.restassured.RestAssured.*;
import static org.hamcrest.CoreMatchers.*;
public class SampleApiTest extends BaseTest {
@Test
void kvstoreTest() {
String path = getPropStr("kvstore.Host") + getPropStr("kvstore.Path.Parakeet") + getPropStr("kvstore.testKey");
given().
headers("kvstoreio_api_key", getPropStr("kvstoreio_api_key")).
when().
get(path).
then().
body("value", is(getPropStr("kvstore.testExpected.value")));
}
}
We can run this test by: mvn test -Dtest=SampleApiTest
When we write integration tests, we consider three categories of configurable parameters.
Many test developers learned enough to avoid hardcoding stuffs, but often they mix those in one file. Some operation specific parameters such as default timeout value can be easily overridden even if it’s mixed with other properties, but we can’t easily replace the set of environment specific parameters at the operation time. As a result, we see duplicate copies of operation specific parameters embedded in ‘test-env.properties’ and ‘stage-env.properties’. Even worse are ‘part of the test’ properties. UI tests utilizing Page Object Model will come with the xpath strings or other forms of identification for an object on a page. If these are mixed with the aforementioned property files, it would be a nightmare to maintain them.
Number of environment specific parameter files should match number of test environments in concern. Number of operation specific parameters should be ideally one. Operation specific parameters are replaced one by one but rarely by the set. Part of the test parameters should be placed in a same folder structure of the classes that need them. For example, if POM class structure has 3 depth tree structure, the resources files should match it.
In the end, we want to run a test suite like this:
>mvn test -Dgroups=regression -Denv=test-env -Dretry=3
In the beginning, you created a folder.
>mkdir potassium
Then you made it a git repo.
>git init –bare
… wait, I don’t want to deal with github later. I’d rather create a new project on github ‘potassium’ then clone it.
>git clone git@github.com:myorg/potassium.git
>cd potassium
It feels home here. Let’s make it a maven project so we won’t need to worry about java library dependencies.
https://maven.apache.org/guides/getting-started/index.html#How_do_I_make_my_first_Maven_project
>
mvn -B archetype:generate -DgroupId=com.myorg.potassium -DartifactId=potassium -DarchetypeArtifactId=maven-archetype-potassium -DarchetypeVersion=1.4
wait .. I made a mistake of creating the maven project ‘potassium’ under the folder I created as ‘potassium’ and I’m too lazy to fix the issue. I will take those out of the folder.
>mv potassium/* .
>rm -rf potassium
I test it by running a maven command.
>mvn clean install
Nice
Add TestNG dependency and create a base test class.
Google ‘maven testng’ to get
https://mvnrepository.com/artifact/org.testng/testng
Copied block goes to pom.xml but let’s open the project in IntelliJ first to handle this.
Open IntelliJ > Imort a new project > (select potassium folder) > maven
Any dependency will go under <dependencies> block per https://maven.apache.org/pom.html
IntelliJ’s .iml file is better staying local to individual developers. I’d leave it out of git repo. Creating .gitignore file to add *.iml pattern might be useful.
>vi .gitignore
>git add .gitignore
>git add pom.xml
Now we’re ready to add a Base class and BaseTest class.
public class Base { private static Properties properties; // this should exist as a singleton Logger logger; Base() { try { properties = new Properties(); InputStream stream = getClass().getClassLoader().getResourceAsStream("default.properties"); properties.load(stream); } catch (IOException e) { e.printStackTrace(); } logger = Logger.getLogger(getClass().getName()); } Properties getProperties() { return properties; } void info(String str) { logger.log(Level.INFO, str); } }
public class BaseTest extends Base
{
BaseTest() {
super();
}
@Parameters({"env"})
@BeforeSuite(alwaysRun = true)
public void beforeSuite(@Optional("test-env") String envName) {
loadTestProperties(envName + ".properties");
}
void loadTestProperties(String envFile) {
try {
info("loading properties: " + envFile);
InputStream stream = getClass().getClassLoader().getResourceAsStream(envFile);
getProperties().load(stream);
} catch (IOException e) {
e.printStackTrace();
}
}
}
public class PropertiesTest extends BaseTest { @Test public void defaultPropertiesTest() { Assert.assertEquals(getPropStr("frameworkName"), getPropStr("expectedName")); } }
>mvn test