0

I have a LeanFT testsuite with TestNG framework in IntelliJ IDEA. I generate jar file with mvn install command. I get error message when I try to execute it:

Error: Could not find or load main class test.LeanFTest

LeanFTest class is present in test named package and contains following lines:

public class LeanFTest {
    public static void main(String[] args) throws IOException, SAXException, ParserConfigurationException {
        TestNG testNG = new TestNG();
        testNG.setTestSuites(Arrays.asList("testng.xml"));
        testNG.setPreserveOrder(true);
        testNG.run();
}

testng.xml file:

<suite name="MyTestSuite" verbose="2" parallel="methods" thread-count="1">

    <listeners>
        <listener class-name="utils.TestNGListener"></listener>
    </listeners>

    <test name="Regression" parallel="false" >
        <classes>
            <class name="test.RegressionTest" />
        </classes>
    </test>

</suite>

I use following plugins in pom.xml:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <version>3.0.1</version>
    <executions>
        <execution>
            <id>copy-dependencies</id>
            <phase>package</phase>
            <goals>
                <goal>copy-dependencies</goal>
            </goals>
            <configuration>
                <outputDirectory>${project.build.directory}/lib</outputDirectory>
                <overWriteIfNewer>true</overWriteIfNewer>
                <overWriteReleases>false</overWriteReleases>
                <overWriteSnapshots>true</overWriteSnapshots>
            </configuration>
        </execution>
    </executions>
</plugin>
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <version>3.0.2</version>
    <configuration>
        <archive>
            <manifest>
                <addClasspath>true</addClasspath>
                <classpathPrefix>lib/</classpathPrefix>
                <mainClass>test.LeanFTest</mainClass>
            </manifest>
        </archive>
        <excludes>
            <exclude>log4j2.xml</exclude>
        </excludes>
    </configuration>
</plugin>
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-assembly-plugin</artifactId>
    <version>3.0.0</version>
    <executions>
        <execution>
            <id>make-assembly</id>
            <phase>package</phase>
            <goals>
                <goal>single</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <finalName>${project.artifactId}-${project.version}</finalName>
        <appendAssemblyId>false</appendAssemblyId>
        <descriptors>
            <descriptor>src/main/assembly/leanft-assembly.xml</descriptor>
        </descriptors>
    </configuration>
</plugin>

leanft-assembly.xml file:

<?xml version="1.0"?>
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">

    <id>fat-tests</id>
    <formats>
        <format>jar</format>
    </formats>
    <includeBaseDirectory>false</includeBaseDirectory>
    <dependencySets>
        <dependencySet>
            <outputDirectory>/</outputDirectory>
            <useProjectArtifact>true</useProjectArtifact>
            <unpack>true</unpack>
            <scope>test</scope>
        </dependencySet>
    </dependencySets>
    <fileSets>
        <fileSet>
            <directory>${project.build.directory}/test-classes</directory>
            <outputDirectory>/</outputDirectory>
            <includes>
                <include>*.class</include>
            </includes>
            <useDefaultExcludes>true</useDefaultExcludes>
        </fileSet>
    </fileSets>
</assembly>

UPDATE: I checked JAR file and found, that it contains files from /src/main/ project folder, but doesn't contains /src/test/ folder, where test classes are located.

UPDATE 06.27. My project structure is the same as in this sample project: https://github.com/kohli-harshit/leanft-testng-template

plaidshirt
  • 5,189
  • 19
  • 91
  • 181

2 Answers2

1

LeanFTest class should must contain @Test annotation and Not Java main method. TestNG will not invoke java main method. So whichever class(RegressionTest) you wants to call, Make sure it has @Test annotation to call.

You can check script by executing it with TestNG Run without executing from .XML file.

Ishita Shah
  • 3,955
  • 2
  • 27
  • 51
  • When I execute `LeanFTest` class from `IntelliJ IDEA`, it starts execution of `RegressionTest`. So it is working properly from IDE. – plaidshirt Jun 25 '18 at 07:26
  • You are executing it from textng.xml so testng parameter is looking for @Test annotation and not java main method. Have you got error to run using Test annotation on LEanFTest class ? – Ishita Shah Jun 25 '18 at 09:15
  • I added `@Test` annotation to `LeanFTest` class, but there aren't any changes, has same effect. – plaidshirt Jun 25 '18 at 11:12
  • I checked JAR file and found, that it contains files from /src/main folder, but doesn't contains /src/test folder, where test classes are located. – plaidshirt Jun 25 '18 at 11:19
1

By default when you build a jar, the classes that reside under src/test/java are never included as part of your jar.

So when you try invoking TestNG via a jar, TestNG wouldn't be able to find it obviously.

Please see this Stackoverflow answer to learn how to build a jar that includes test classes as well.

When you work with an IDE, TestNG would have visibility to all classes under src/main/java and src/test/java which explains why things work from within the IDE.

Update: I have updated the answer with the reference to a proper Stack-overflow answer which solves this problem.

I am duplicating the relevant sections for your reference.

The corresponding maven-jar-plugin and maven-assembly-plugin descriptions from the pom file.

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-jar-plugin</artifactId>
  <executions>
    <execution>
      <goals>
        <goal>test-jar</goal>
      </goals>
    </execution>
  </executions>
</plugin>
<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-assembly-plugin</artifactId>
  <version>3.1.0</version>
  <executions>
    <execution>
      <id>make-assembly</id>
      <phase>package</phase>
      <goals>
        <goal>single</goal>
      </goals>
    </execution>
  </executions>
  <configuration>
    <archive>
      <manifest>
        <mainClass>org.testng.TestNG</mainClass>
      </manifest>
    </archive>
    <appendAssemblyId>false</appendAssemblyId>
    <descriptors>
      <descriptor>src/test/resources/assembly.xml</descriptor>
    </descriptors>
  </configuration>
</plugin>

Contents of the file src/test/resources/assembly.xml

<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
  <id>test-jar-with-dependencies</id>
  <formats>
    <format>jar</format>
  </formats>
  <includeBaseDirectory>false</includeBaseDirectory>
  <dependencySets>
    <dependencySet>
      <outputDirectory>/</outputDirectory>
      <useProjectArtifact>true</useProjectArtifact>
      <!-- we're creating the test-jar as an attachement -->
      <useProjectAttachments>true</useProjectAttachments>
      <unpack>true</unpack>
      <scope>test</scope>
    </dependencySet>
  </dependencySets>
</assembly>

Now when should be able to find your test classes in the created jar when you run mvn clean package. Here we are basically doing two things:

  1. Using the maven-jar-plugin we are first creating a jar that contains the test files (You should see the jar under target/*-tests.jar
  2. Using the maven-assembly-plugin we are now creating an uber jar that includes the test-jar also as an attachment but by including it after unpacking it.
Krishnan Mahadevan
  • 14,121
  • 6
  • 34
  • 66