Skip to content

Commit

Permalink
Move integration tests to own package
Browse files Browse the repository at this point in the history
  • Loading branch information
samuelfangjw committed Feb 6, 2023
1 parent 363eb8a commit f676354
Show file tree
Hide file tree
Showing 10 changed files with 174 additions and 7 deletions.
30 changes: 28 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -117,13 +117,15 @@ sourceSets {
srcDir "src/test/java"
srcDir "src/e2e/java"
srcDir "src/lnp/java"
srcDir "src/it/java"
srcDir "src/client/java"
include "**/*.java"
}
resources {
srcDir "src/test/resources"
srcDir "src/e2e/resources"
srcDir "src/lnp/resources"
srcDir "src/it/resources"
srcDir "src/client/resources"
exclude "**/*.java"
}
Expand Down Expand Up @@ -536,8 +538,8 @@ task lnpTests(type: Test) {
}
}

task componentTests(type: Test) {
description "Runs the full unit and integration test suite."
task unitTests(type: Test) {
description "Runs the full unit test suite."
group "Test"
useTestNG()
options.suites "src/test/resources/testng-component.xml"
Expand All @@ -554,6 +556,30 @@ task componentTests(type: Test) {
}
}

task integrationTests(type: Test) {
description "Runs the full integration test suite."
group "Test"
useTestNG()
options.suites "src/it/resources/testng-it.xml"
options.useDefaultListeners = true
ignoreFailures false
maxHeapSize = "1g"
reports.html.required = false
reports.junitXml.required = false
jvmArgs "-ea", "-Xss2m", "-Dfile.encoding=UTF-8"
afterTest afterTestClosure
afterSuite checkTestNgFailureClosure
testLogging {
events "passed"
}
}

task componentTests(type: Test) {
description "Runs the full unit and integration test suite."
group "Test"
dependsOn unitTests, integrationTests
}

task e2eTests {
description "Runs the full E2E test suite and retries failed test up to ${numOfTestRetries} times."
group "Test"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
package teammates.storage.sqlapi;
package teammates.it.storage.sqlapi;

import org.testng.annotations.Test;

import teammates.common.exception.EntityAlreadyExistsException;
import teammates.common.exception.EntityDoesNotExistException;
import teammates.it.test.BaseTestCaseWithSqlDatabaseAccess;
import teammates.storage.sqlapi.CoursesDb;
import teammates.storage.sqlentity.Course;
import teammates.test.BaseTestCaseWithSqlDatabaseAccess;

/**
* SUT: {@link CoursesDb}.
Expand Down
4 changes: 4 additions & 0 deletions src/it/java/teammates/it/storage/sqlapi/package-info.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/**
* Contains test cases for {@link teammates.storage.search} package.
*/
package teammates.it.storage.sqlapi;
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package teammates.test;
package teammates.it.test;

import org.testcontainers.containers.PostgreSQLContainer;
import org.testng.annotations.AfterMethod;
Expand All @@ -13,6 +13,7 @@
import teammates.sqllogic.core.LogicStarter;
import teammates.storage.sqlentity.BaseEntity;
import teammates.storage.sqlentity.Course;
import teammates.test.BaseTestCase;

/**
* Base test case for tests that access the database.
Expand Down Expand Up @@ -51,7 +52,10 @@ public void tearDown() {
HibernateUtil.getSessionFactory().getCurrentSession().getTransaction().commit();
}

public void verifyEquals(BaseEntity expected, BaseEntity actual) {
/**
* Verifies that two entities are equal.
*/
protected void verifyEquals(BaseEntity expected, BaseEntity actual) {
if (expected instanceof Course) {
Course expectedCourse = (Course) expected;
Course actualCourse = (Course) actual;
Expand All @@ -60,6 +64,9 @@ public void verifyEquals(BaseEntity expected, BaseEntity actual) {
}
}

/**
* Verifies that the given entity is present in the database.
*/
protected void verifyPresentInDatabase(BaseEntity expected) {
BaseEntity actual = getEntity(expected);
verifyEquals(expected, actual);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package teammates.test;
package teammates.it.test;

import java.io.File;
import java.sql.Connection;
Expand Down
95 changes: 95 additions & 0 deletions src/it/java/teammates/it/test/TestNgXmlTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package teammates.it.test;

import java.io.File;
import java.util.HashMap;
import java.util.Map;

import org.testng.annotations.Test;

import teammates.test.BaseTestCase;
import teammates.test.FileHelper;

/**
* Verifies that the testng-it.xml configuration file contains all the integration test cases in the project.
*/
public class TestNgXmlTest extends BaseTestCase {

@Test
public void checkTestsInTestNg() throws Exception {
String testNgXml = FileHelper.readFile("./src/it/resources/testng-it.xml");

// <class name, package name>
Map<String, String> testFiles = getTestFiles(testNgXml, "./src/it/java/teammates");

testFiles.forEach((key, value) -> assertTrue(isTestFileIncluded(testNgXml, value, key)));
}

/**
* Files to be checked in testng-it.xml are added to testFiles.
*
* @param testNgXml Contents of testng-it.xml
* @param rootPath Root path of test files
* @return Map containing {@code <class name, package name>}
*/
private Map<String, String> getTestFiles(String testNgXml, String rootPath) {
// BaseComponentTestCase, BaseTestCase (files in current directory) excluded because
// base classes are extended by the actual tests

return addFilesToTestsRecursively(rootPath, true, "teammates", testNgXml);
}

private boolean isTestFileIncluded(String testNgXml, String packageName, String testClassName) {
return testNgXml.contains("<class name=\"" + packageName + "." + testClassName + "\" />");
}

/**
* Recursively adds files from testng-it.xml which are to be checked.
*
* @param path Check files and directories in the current path
*
* @param areFilesInCurrentDirExcluded If true, files in the current path are not
* added to tests but sub-directories are still checked
*
* @param packageName Package name of the current file
* @param testNgXml Contents of testng-component.xml
*
* @return Map containing {@code <class name, package name>} including
* current file or tests in the current directory
*/
private Map<String, String> addFilesToTestsRecursively(String path, boolean areFilesInCurrentDirExcluded,
String packageName, String testNgXml) {

Map<String, String> testFiles = new HashMap<>();
File folder = new File(path);
File[] listOfFiles = folder.listFiles();
if (listOfFiles == null) {
return testFiles;
}

for (File file : listOfFiles) {
String name = file.getName();

if (file.isFile() && name.endsWith(".java") && !name.startsWith("package-info")
&& !areFilesInCurrentDirExcluded) {
testFiles.put(name.replace(".java", ""), packageName);

} else if (file.isDirectory() && !name.endsWith("browsertests") && !name.endsWith("pageobjects")
&& !name.endsWith("architecture")) {
// If the package name is in TestNG in the form of <package name="teammates.package.name" />
// then files in the current directory are excluded because the whole package would be tested by TestNG.

testFiles.putAll(
addFilesToTestsRecursively(path + "/" + name,
isPackageNameInTestNg(packageName + "." + name, testNgXml),
packageName + "." + name, testNgXml));
}
}

return testFiles;
}

private boolean isPackageNameInTestNg(String packageName, String testNgXml) {
return testNgXml.contains("<package name=\"" + packageName + "\" />");
}

}
4 changes: 4 additions & 0 deletions src/it/java/teammates/it/test/package-info.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/**
* Contains infrastructure and helpers needed for running the integration tests.
*/
package teammates.it.test;
11 changes: 11 additions & 0 deletions src/it/resources/testng-it.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="component-tests">
<test name="component-tests">
<packages>
<package name="teammates.it" />
<package name="teammates.it.test" />
<package name="teammates.it.storage.sqlapi" />
</packages>
</test>
</suite>
18 changes: 18 additions & 0 deletions src/test/java/teammates/ui/servlets/WebApiServletTest.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package teammates.ui.servlets;

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import java.util.Collections;
import java.util.HashMap;
import java.util.List;
Expand All @@ -8,11 +11,16 @@
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

import com.google.cloud.datastore.DatastoreException;

import teammates.common.util.Const;
import teammates.common.util.HibernateUtil;
import teammates.test.BaseTestCase;
import teammates.test.MockHttpServletRequest;
import teammates.test.MockHttpServletResponse;
Expand All @@ -30,6 +38,16 @@ public class WebApiServletTest extends BaseTestCase {
private MockHttpServletRequest mockRequest;
private MockHttpServletResponse mockResponse;

@BeforeClass
public static void classSetup() {
SessionFactory sessionFactory = mock(SessionFactory.class);
Session session = mock(Session.class);
Transaction transaction = mock(Transaction.class);
when(sessionFactory.getCurrentSession()).thenReturn(session);
when(session.getTransaction()).thenReturn(transaction);
HibernateUtil.setSessionFactory(sessionFactory);
}

private void setupMocks(String method, String requestUrl) {
mockRequest = new MockHttpServletRequest(method, requestUrl);
mockResponse = new MockHttpServletResponse();
Expand Down
1 change: 1 addition & 0 deletions static-analysis/teammates-pmdMain.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
<exclude-pattern>.*/test/java/.*</exclude-pattern>
<exclude-pattern>.*/e2e/java/.*</exclude-pattern>
<exclude-pattern>.*/lnp/java/.*</exclude-pattern>
<exclude-pattern>.*/it/java/.*</exclude-pattern>
<exclude-pattern>.*/client/java/.*</exclude-pattern>
<exclude-pattern>.*.html</exclude-pattern>
<exclude-pattern>.*.xml</exclude-pattern>
Expand Down

0 comments on commit f676354

Please sign in to comment.