diff --git a/.gitignore b/.gitignore index 7dec39d..a04adfe 100644 --- a/.gitignore +++ b/.gitignore @@ -22,4 +22,8 @@ hs_err_pid* # IntelliJ IDEA -.idea \ No newline at end of file +.idea +Output_TestSmellDetection* +target/ +TestSmellDetector.iml +files-smell.csv \ No newline at end of file diff --git a/TestSmellDetector.iml b/TestSmellDetector.iml deleted file mode 100644 index 3735e2c..0000000 --- a/TestSmellDetector.iml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/pom.xml b/pom.xml index af5379a..879b4e7 100644 --- a/pom.xml +++ b/pom.xml @@ -7,6 +7,7 @@ edu.rit.se.testsmells TestSmellDetector 0.1 + jar @@ -17,6 +18,42 @@ 1.8 + + org.apache.maven.plugins + maven-surefire-plugin + 3.0.0-M4 + + + org.junit.vintage + junit-vintage-engine + 5.4.2 + + + + + org.apache.maven.plugins + maven-assembly-plugin + + + package + + single + + + + + + Main + + + + + jar-with-dependencies + + + + + @@ -31,7 +68,24 @@ opencsv 3.9 - + + junit + junit + 4.12 + test + + + org.junit.jupiter + junit-jupiter-api + 5.4.2 + test + + + org.junit.jupiter + junit-jupiter-engine + 5.4.2 + test + \ No newline at end of file diff --git a/src/main/java/Main.java b/src/main/java/Main.java index 9e691b8..94f6786 100644 --- a/src/main/java/Main.java +++ b/src/main/java/Main.java @@ -2,6 +2,8 @@ import testsmell.ResultsWriter; import testsmell.TestFile; import testsmell.TestSmellDetector; +import testsmell.smell.AssertionRoulette; +import testsmell.smell.EagerTest; import java.io.BufferedReader; import java.io.File; @@ -27,8 +29,7 @@ public static void main(String[] args) throws IOException { } } - - TestSmellDetector testSmellDetector = TestSmellDetector.createTestSmellDetector(); + TestSmellDetector testSmellDetector = new TestSmellDetector(); /* Read the input file and build the TestFile objects @@ -63,7 +64,7 @@ public static void main(String[] args) throws IOException { columnNames = testSmellDetector.getTestSmellNames(); columnNames.add(0, "App"); - columnNames.add(1, "Version"); + columnNames.add(1, "TestClass"); columnNames.add(2, "TestFilePath"); columnNames.add(3, "ProductionFilePath"); columnNames.add(4, "RelativeTestFilePath"); @@ -88,7 +89,7 @@ public static void main(String[] args) throws IOException { //write output columnValues = new ArrayList<>(); columnValues.add(file.getApp()); - columnValues.add(file.getTagName()); + columnValues.add(file.getTestFileName()); columnValues.add(file.getTestFilePath()); columnValues.add(file.getProductionFilePath()); columnValues.add(file.getRelativeTestFilePath()); diff --git a/src/main/java/testsmell/TestFile.java b/src/main/java/testsmell/TestFile.java index 90f8d03..333ba84 100644 --- a/src/main/java/testsmell/TestFile.java +++ b/src/main/java/testsmell/TestFile.java @@ -2,6 +2,7 @@ import org.apache.commons.lang3.StringUtils; +import java.io.File; import java.util.ArrayList; import java.util.List; @@ -40,13 +41,18 @@ public void addSmell(AbstractSmell smell) { testSmells.add(smell); } + /** + * Supposed to return the version of the project. + * Returns the "N.I.Y", Not Implemented Yet string + * todo: not implemented in any way yet + */ public String getTagName(){ - return testFilePath.split("\\\\")[4]; + return "N.I.Y"; } public String getTestFileName(){ - int lastIndex = testFilePath.lastIndexOf("\\"); - return testFilePath.substring(lastIndex+1,testFilePath.length()); + int lastIndex = testFilePath.lastIndexOf(File.separator); + return testFilePath.substring(lastIndex+1); } public String getTestFileNameWithoutExtension(){ @@ -62,32 +68,40 @@ public String getProductionFileNameWithoutExtension(){ } public String getProductionFileName(){ - int lastIndex = productionFilePath.lastIndexOf("\\"); + int lastIndex = productionFilePath.lastIndexOf(File.separator); if(lastIndex==-1) return ""; - return productionFilePath.substring(lastIndex+1,productionFilePath.length()); + return productionFilePath.substring(lastIndex+1); } + /** + * Returns the path of the test file relative to the folder with the name of the project. + * If the project directory has a different name, returns an empty string. + * @return the relative test file path + */ public String getRelativeTestFilePath() { - String[] splitString = testFilePath.split("\\\\"); - StringBuilder stringBuilder = new StringBuilder(); - for (int i = 0; i < 5; i++) { - stringBuilder.append(splitString[i] + "\\"); - } - return testFilePath.substring(stringBuilder.toString().length()).replace("\\", "/"); + if (!StringUtils.isEmpty(testFilePath)) { + int projectNameIndex = testFilePath.lastIndexOf(app); + if (projectNameIndex == -1) + return ""; + return testFilePath.substring(projectNameIndex+app.length()+File.separator.length()); + } else + return ""; } + /** + * Returns the path of the production file relative to the folder with the name of the project. + * If the project directory has a different name, returns an empty string. + * @return the relative production file path + * + */ public String getRelativeProductionFilePath() { if (!StringUtils.isEmpty(productionFilePath)) { - String[] splitString = productionFilePath.split("\\\\"); - StringBuilder stringBuilder = new StringBuilder(); - for (int i = 0; i < 5; i++) { - stringBuilder.append(splitString[i] + "\\"); - } - return productionFilePath.substring(stringBuilder.toString().length()).replace("\\", "/"); - } else { + int projectNameIndex = productionFilePath.lastIndexOf(app); + if (projectNameIndex == -1) + return ""; + return productionFilePath.substring(projectNameIndex+app.length()+File.separator.length()); + } else return ""; - - } } } \ No newline at end of file diff --git a/src/main/java/testsmell/TestSmellDetector.java b/src/main/java/testsmell/TestSmellDetector.java index 6e54184..a76fad3 100644 --- a/src/main/java/testsmell/TestSmellDetector.java +++ b/src/main/java/testsmell/TestSmellDetector.java @@ -23,6 +23,8 @@ public TestSmellDetector() { initializeSmells(); } + public TestSmellDetector(boolean initialize) {} + private void initializeSmells(){ testSmells = new ArrayList<>(); testSmells.add(new AssertionRoulette()); @@ -48,6 +50,10 @@ private void initializeSmells(){ testSmells.add(new DependentTest()); } + public void setTestSmells(List testSmells) { + this.testSmells = testSmells; + } + /** * Factory method that provides a new instance of the TestSmellDetector * @@ -83,7 +89,7 @@ public TestFile detectSmells(TestFile testFile) throws IOException { productionFileCompilationUnit = JavaParser.parse(productionFileInputStream); } - initializeSmells(); +// initializeSmells(); for (AbstractSmell smell : testSmells) { try { smell.runAnalysis(testFileCompilationUnit, productionFileCompilationUnit,testFile.getTestFileNameWithoutExtension(),testFile.getProductionFileNameWithoutExtension()); diff --git a/src/main/java/testsmell/smell/AssertionRoulette.java b/src/main/java/testsmell/smell/AssertionRoulette.java index d4ddb92..ff196db 100644 --- a/src/main/java/testsmell/smell/AssertionRoulette.java +++ b/src/main/java/testsmell/smell/AssertionRoulette.java @@ -21,6 +21,7 @@ public class AssertionRoulette extends AbstractSmell { private List smellyElementList; + private int assertionsCount = 0; public AssertionRoulette() { smellyElementList = new ArrayList<>(); @@ -50,6 +51,11 @@ public void runAnalysis(CompilationUnit testFileCompilationUnit, CompilationUnit AssertionRoulette.ClassVisitor classVisitor; classVisitor = new AssertionRoulette.ClassVisitor(); classVisitor.visit(testFileCompilationUnit, null); + assertionsCount = classVisitor.overallAssertions; + } + + public int getAssertionsCount() { + return assertionsCount; } /** @@ -65,6 +71,7 @@ private class ClassVisitor extends VoidVisitorAdapter { private MethodDeclaration currentMethod = null; private int assertNoMessageCount = 0; private int assertCount = 0; + private int overallAssertions = 0; TestMethod testMethod; // examine all methods in the test class @@ -89,6 +96,7 @@ else if (assertNoMessageCount >= 1) //if there is more than one assert statement //reset values for next method currentMethod = null; + overallAssertions += assertCount; assertCount = 0; assertNoMessageCount = 0; } @@ -104,6 +112,7 @@ public void visit(MethodCallExpr n, Void arg) { n.getNameAsString().startsWith(("assertEquals")) || n.getNameAsString().startsWith(("assertNotSame")) || n.getNameAsString().startsWith(("assertSame")) || + n.getNameAsString().startsWith("assertThrows") || n.getNameAsString().startsWith(("assertThat"))) { assertCount++; // assert methods that do not contain a message diff --git a/src/main/java/testsmell/smell/EagerTest.java b/src/main/java/testsmell/smell/EagerTest.java index 2683313..7412616 100644 --- a/src/main/java/testsmell/smell/EagerTest.java +++ b/src/main/java/testsmell/smell/EagerTest.java @@ -24,6 +24,7 @@ public class EagerTest extends AbstractSmell { private String productionClassName; private List smellyElementList; private List productionMethods; + private int eagerCount; public EagerTest() { productionMethods = new ArrayList<>(); @@ -62,7 +63,7 @@ public void runAnalysis(CompilationUnit testFileCompilationUnit, CompilationUnit classVisitor = new EagerTest.ClassVisitor(TEST_FILE); classVisitor.visit(testFileCompilationUnit, null); - + eagerCount = classVisitor.overallEager; } /** @@ -73,6 +74,9 @@ public List getSmellyElements() { return smellyElementList; } + public int getEagerCount() { + return eagerCount; + } /** * Visitor class @@ -81,6 +85,7 @@ private class ClassVisitor extends VoidVisitorAdapter { private MethodDeclaration currentMethod = null; TestMethod testMethod; private int eagerCount = 0; + private int overallEager = 0; private List productionVariables = new ArrayList<>(); private List calledMethods = new ArrayList<>(); private String fileType; @@ -123,6 +128,7 @@ public void visit(MethodDeclaration n, Void arg) { //reset values for next method currentMethod = null; + overallEager += eagerCount; eagerCount = 0; productionVariables = new ArrayList<>(); calledMethods = new ArrayList<>(); diff --git a/src/test/java/testsmell/TestFileTest.java b/src/test/java/testsmell/TestFileTest.java new file mode 100644 index 0000000..54e0d52 --- /dev/null +++ b/src/test/java/testsmell/TestFileTest.java @@ -0,0 +1,92 @@ +package testsmell; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.condition.EnabledOnOs; +import org.junit.jupiter.api.condition.OS; + +import static org.junit.jupiter.api.Assertions.*; + +class TestFileTest { + + private String fileTest = "commons-lang," + + "/Users/grano/projects/commons-lang/src/test/java/org/apache/commons/lang3/RandomStringUtilsTest.java," + + "/Users/grano/projects/commons-lang/src/main/java/org/apache/commons/lang3/RandomStringUtils.java"; + private String fileTestWindows = "myCoolApp," + + "F:\\Apps\\myCoolApp\\code\\test\\GraphTest.java," + + "F:\\Apps\\myCoolApp\\code\\src\\Graph.java"; + private TestFile testFileUnix; + private TestFile testFileWindows; + + @BeforeEach + void setUp() { + String[] splits = fileTest.split(","); + testFileUnix = new TestFile(splits[0], splits[1], splits[2]); + String[] splitW = fileTestWindows.split(","); + testFileWindows = new TestFile(splitW[0], splitW[1], splitW[2]); + } + + @Test + @EnabledOnOs({OS.WINDOWS}) + public void testGetFileNameWindows() { + String oracle = "GraphTest.java"; + String output = testFileWindows.getTestFileName(); + assertEquals(oracle, output); + } + + @Test + @EnabledOnOs({OS.LINUX, OS.MAC}) + public void testGetFileNameUnix() { + String oracle = "RandomStringUtilsTest.java"; + String output = testFileUnix.getTestFileName(); + assertEquals(oracle, output); + } + + @Test + @EnabledOnOs({OS.WINDOWS}) + public void testProductionFileNameWindows() { + String oracle = "Graph.java"; + String output = testFileWindows.getProductionFileName(); + assertEquals(oracle, output); + } + + @Test + @EnabledOnOs({OS.LINUX, OS.MAC}) + public void testGetProductionFileNameUnix() { + String oracle = "RandomStringUtils.java"; + String output = testFileUnix.getProductionFileName(); + assertEquals(oracle, output); + } + + @Test + @EnabledOnOs({OS.LINUX, OS.MAC}) + public void testGetRelativeProductionFilePathUnix() { + String oracle = "src/main/java/org/apache/commons/lang3/RandomStringUtils.java"; + String output = testFileUnix.getRelativeProductionFilePath(); + assertEquals(oracle, output); + } + + @Test + @EnabledOnOs({OS.LINUX, OS.MAC}) + public void testGetRelativeTestFilePathUnix() { + String oracle = "src/test/java/org/apache/commons/lang3/RandomStringUtilsTest.java"; + String output = testFileUnix.getRelativeTestFilePath(); + assertEquals(oracle, output); + } + + @Test + @EnabledOnOs({OS.WINDOWS}) + public void testGetRelativeProductionFilePathWindows() { + String oracle = "code\\src\\Graph.java"; + String output = testFileWindows.getRelativeProductionFilePath(); + assertEquals(oracle, output); + } + + @Test + @EnabledOnOs({OS.WINDOWS}) + public void testGetRelativeTestFilePathWindows() { + String oracle = "code\\test\\GraphTest.java"; + String output = testFileWindows.getRelativeTestFilePath(); + assertEquals(oracle, output); + } +} \ No newline at end of file