Postgres DB
In this example, we would see how to query a Postgres database table. Let’s create a postgres database called testdb
. Let’s also create a table otp_details
and populate it with few rows.
testdb=# SELECT otp FROM otp_details WHERE mobileNumber='9898989898';
otp
--------
321123
(1 row)
Provide database connection details
Open resources/db/drivers.yml
file
It has below template:
<KEY>:
host: "<HOST>"
port: "<PORT>"
username: "${env:DB_USERNAME}"
password: "${env:DB_PASSWORD}"
Now fill the template with connection details. Please note that Ekam would refer to the <KEY>
for reading the connection details.
authentication:
host: "localhost"
port: "5432"
username: "postgres"
password: ""
Create query
Create an interface with name Queries under db/clients
and declare select query as shown
package ekam.example.db.clients;
import org.skife.jdbi.v2.sqlobject.Bind;
import org.skife.jdbi.v2.sqlobject.SqlQuery;
public interface Queries {
@SqlQuery("SELECT otp FROM otp_details WHERE mobileNumber = :mobileNumber")
String getOtp(@Bind("mobileNumber") String mobileNumber);
}
Create a Database Client
Let us create a database client class that calls the query and returns otp for a given mobile number.
package ekam.example.db.clients;
import com.testvagrant.ekam.db.clients.PostgresDBClient;
public class AuthenticationDBClient extends PostgresDBClient {
private final Queries queries;
protected AuthenticationDBClient() {
super("testdb", "authentication");
queries = load(Queries.class);
}
public String getOTP(String mobileNumber) {
return queries.getOtp(mobileNumber);
}
}
Add & execute test
- Inject the AuthenticationDBClient
- Use the injected instance to query
package ekam.example.db.clients;
import com.google.inject.Inject;
import com.testvagrant.ekam.testBases.testng.APITest;
import org.testng.Assert;
import org.testng.annotations.Test;
public class DatabaseQueryTest extends APITest {
@Inject
AuthenticationDBClient client;
@Test(groups = "db")
public void shouldGetOtp() {
String otp = client.getOTP("9898989898");
System.out.println(otp);
Assert.assertNotNull(otp);
}
}
Execute the test from IDE
How to avoid plain text of user credentials on the drivers.yml file?
It is not a good practice to specify clear text passwords in any of the source files and configurations. Pass the username & password as a command-line argument.
Use this syntax "${env: <arg name>}"
for the required fields in the drivers.yml
file, provided an example below:
authentication:
host: "localhost"
port: "5432"
username: "${env:DB_USERNAME}"
password: "${env:DB_PASSWORD}"
Pass these as system properties to Gradle task:
systemProperties = [
config: System.getProperty("config"),
DB_USERNAME: System.getProperty("DB_USERNAME"),
DB_PASSWORD: System.getProperty("DB_PASSWORD")
]
Complete Gradle Task:
task runDbTests(type: Test) {
systemProperties = [
config: System.getProperty("config"),
DB_USERNAME: System.getProperty("DB_USERNAME"),
DB_PASSWORD: System.getProperty("DB_PASSWORD")
]
filter {
excludeTestsMatching "*.mobile.*"
excludeTestsMatching "*.api.*"
excludeTestsMatching "*.web.*"
}
outputs.upToDateWhen { false }
useTestNG {
parallel = "methods"
threadCount Integer.parseInt(System.getProperty("sessions", "2"))
includeGroups System.getProperty("tags", "db")
testLogging.showStandardStreams = true
useDefaultListeners true
outputDirectory = file("$buildDir/" + System.getProperty('tags', 'NONE'))
}
}
Execute tests via gradle task
./gradlew runDbTests -DDB_USERNAME=<username> -DDB_PASSWORD=<password>