How to maintain folder structure while exporting t

2019-08-21 04:19发布

I am trying to find a solution for this from the past one week and have posted a question regarding the same.

I have created a simple Maven Project. And have written a feature file which is open browser, go to facebook and close the browser.

First of all, below is the project structure,

Project Structure

Below is my feature file. Name of the feature file is Testing.feature

Feature: Open FB
Scenario: Open FB
    Given User opens "facebookURL" on "ChromeBr"
    When User is on facebook
    Then close the browser

Then I wrote a stepdefinition for the above feature file. Name of the step definition file is Testing.java

package stepDefinitions;

import cucumber.api.java.en.Given;
import cucumber.api.java.en.Then;
import cucumber.api.java.en.When;
import util.WebConnector;

public class Testing {
    WebConnector wc = WebConnector.getInstance();
    @Given("^User opens \"([^\"]*)\" on \"([^\"]*)\"$")
    public void user_opens_on(String URL, String Browser) throws Throwable {
        wc.openBrowser(Browser);
        wc.navigateURL(URL);
        System.out.println("Browser Opened & navigated to FB");
    }


    @When("^User is on facebook$")
    public void user_is_on_facebook() throws Throwable {
        System.out.println("User is on FB");
    }

    @Then("^close the browser$")
    public void close_the_browser() throws Throwable {
        wc.quitBrowser();
        System.out.println("Browser Closed");
    }
}

And config.properties contains only one property

facebookURL=https://www.facebook.com

I written a common class file which is WebConnector.java which will have a constructor for initializing the property file and few methods like open browser and URL etc

package util;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;
import java.util.concurrent.TimeUnit;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

public class WebConnector {
    public Properties OR = null;
    public Properties CONFIG = null;
    public static WebDriver driver;
    static WebConnector w;
    private WebConnector() {
        if(CONFIG==null) {
            try {
                CONFIG = new Properties();
                FileInputStream fis = new FileInputStream(System.getProperty("user.dir")+"\\src\\test\\java\\config\\config.properties"); **//Here only I get error when I export as Runnable Jar and Run**
                CONFIG.load(fis);
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

    public static WebConnector getInstance() {
        if(w==null)
            w=new WebConnector();
            return w;
    }

    public void openBrowser(String browserName) throws IOException {
            System.setProperty("webdriver.chrome.driver", System.getProperty("user.dir")+"\\chromedriver.exe");
            driver = new ChromeDriver();
            driver.manage().window().maximize();
        driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
    }
    public void navigateURL(String URL) throws IOException {
        driver.get(CONFIG.getProperty(URL));
    }

    public void quitBrowser() {
        driver.quit();
    }
}

And this is my test runner class which has a main method. It can be run using Junit as well Java Application

package util;

import org.junit.runner.JUnitCore;
import org.junit.runner.RunWith;
import cucumber.api.CucumberOptions;
import cucumber.api.junit.Cucumber;

@RunWith(Cucumber.class)
@CucumberOptions(
        features = "classpath:feature",
        glue = "stepDefinitions"
        )

public class RunCukesTest {
    public static void main(String[] args) {                    
        JUnitCore.main("util.RunCukesTest");
    }
}

Pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>Jar_Testing</groupId>
  <artifactId>Jar_Testing</artifactId>
  <version>0.0.1-SNAPSHOT</version>


    <dependencies>
        <!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java -->
        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-java</artifactId>
            <version>3.5.3</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/junit/junit -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/info.cukes/cucumber-java -->
        <dependency>
            <groupId>info.cukes</groupId>
            <artifactId>cucumber-java</artifactId>
            <version>1.2.5</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/info.cukes/cucumber-core -->
        <dependency>
            <groupId>info.cukes</groupId>
            <artifactId>cucumber-core</artifactId>
            <version>1.2.5</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/info.cukes/cucumber-junit -->
        <dependency>
            <groupId>info.cukes</groupId>
            <artifactId>cucumber-junit</artifactId>
            <version>1.2.5</version>
            <scope>test</scope>
        </dependency>

    </dependencies>

    <build>
            <plugins>
                <plugin>
                    <artifactId>maven-assembly-plugin</artifactId>
                    <configuration>
                        <descriptorRefs>
                            <descriptorRef>jar-with-dependencies</descriptorRef>
                        </descriptorRefs>
                        <archive>
                            <manifest>
                                <mainClass>util.RunCukesTest</mainClass>
                            </manifest>
                        </archive>
                    </configuration>
                </plugin>
            </plugins>
    </build>

</project>

Problem: When I run RunCukesTest.java, using Junit or Java Application, it runs perfectly. That is, it opens the browser, goes to fb and closes the browser.

But when I create an executable Jar and run, it does not run as expected.

I export as Runnable Jar by following below Steps:

1) Run--> Run Configuration--> Java Application-->New Launch Configuration-->And selects the main class as RunCukesTest.java-->Apply
2) Right click the project-->Export
3) Java--> Runnable JAR File -->Next
4) Under Launch Configuration select the RunCukesTest.java and give the export destination
5) And I have selected the option "Extract required Libraries into Jar"
5) click finish

Say I have saved this Jar in My desktop. desktop path-->"C:\Users\PC\Desktop" When I run this Jar from command prompt, it shows the below

C:\Users\PC\Downloads>java -jar Maven.jar
JUnit version 4.12
.java.io.FileNotFoundException: C:\Users\PC\Downloads\src\test\java\config\c
onfig.properties (The system cannot find the path specified)
        at java.io.FileInputStream.open0(Native Method)
        at java.io.FileInputStream.open(FileInputStream.java:195)
        at java.io.FileInputStream.<init>(FileInputStream.java:138)
        at java.io.FileInputStream.<init>(FileInputStream.java:93)
        at util.WebConnector.<init>(WebConnector.java:19)
        at util.WebConnector.getInstance(WebConnector.java:30)
        at stepDefinitions.Testing.<init>(Testing.java:9)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)

        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstruct
orAccessorImpl.java:62)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingC
onstructorAccessorImpl.java:45)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
        at cucumber.runtime.java.DefaultJavaObjectFactory.cacheNewInstance(Defau
ltJavaObjectFactory.java:41)
        at cucumber.runtime.java.DefaultJavaObjectFactory.getInstance(DefaultJav
aObjectFactory.java:33)
        at cucumber.runtime.java.JavaStepDefinition.execute(JavaStepDefinition.j
ava:38)
        at cucumber.runtime.StepDefinitionMatch.runStep(StepDefinitionMatch.java
:37)
        at cucumber.runtime.Runtime.runStep(Runtime.java:300)
        at cucumber.runtime.model.StepContainer.runStep(StepContainer.java:44)
        at cucumber.runtime.model.StepContainer.runSteps(StepContainer.java:39)
        at cucumber.runtime.model.CucumberScenario.run(CucumberScenario.java:44)

        at cucumber.runtime.junit.ExecutionUnitRunner.run(ExecutionUnitRunner.ja
va:102)
        at cucumber.runtime.junit.FeatureRunner.runChild(FeatureRunner.java:63)
        at cucumber.runtime.junit.FeatureRunner.runChild(FeatureRunner.java:18)
        at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
        at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
        at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
        at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
        at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
        at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
        at cucumber.runtime.junit.FeatureRunner.run(FeatureRunner.java:70)
        at cucumber.api.junit.Cucumber.runChild(Cucumber.java:95)
        at cucumber.api.junit.Cucumber.runChild(Cucumber.java:38)
        at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
        at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
        at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
        at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
        at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
        at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
        at cucumber.api.junit.Cucumber.run(Cucumber.java:100)
        at org.junit.runners.Suite.runChild(Suite.java:128)
        at org.junit.runners.Suite.runChild(Suite.java:27)
        at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
        at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
        at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
        at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
        at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
        at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
        at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
        at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
        at org.junit.runner.JUnitCore.runMain(JUnitCore.java:77)
        at org.junit.runner.JUnitCore.main(JUnitCore.java:36)
        at util.RunCukesTest.main(RunCukesTest.java:16)
.EEII
←[31mFailed scenarios:←[0m
←[31mfeature/Testing.feature:3 ←[0m# Scenario: Open FB

1 Scenarios (←[31m1 failed←[0m)
3 Steps (←[31m1 failed←[0m, ←[36m2 skipped←[0m)
0m0.314s

java.lang.IllegalStateException: The driver executable does not exist: C:\Users\
PC\Downloads\chromedriver.exe
        at com.google.common.base.Preconditions.checkState(Preconditions.java:53
4)
        at org.openqa.selenium.remote.service.DriverService.checkExecutable(Driv
erService.java:136)
        at org.openqa.selenium.remote.service.DriverService.findExecutable(Drive
rService.java:131)
        at org.openqa.selenium.chrome.ChromeDriverService.access$000(ChromeDrive
rService.java:32)
        at org.openqa.selenium.chrome.ChromeDriverService$Builder.findDefaultExe
cutable(ChromeDriverService.java:137)
        at org.openqa.selenium.remote.service.DriverService$Builder.build(Driver
Service.java:329)
        at org.openqa.selenium.chrome.ChromeDriverService.createDefaultService(C
hromeDriverService.java:88)
        at org.openqa.selenium.chrome.ChromeDriver.<init>(ChromeDriver.java:124)

        at util.WebConnector.openBrowser(WebConnector.java:36)
        at stepDefinitions.Testing.user_opens_on(Testing.java:12)
        at ?.Given User opens "facebookURL" on "ChromeBr"(feature/Testing.featur
e:4)


Time: 0.359
There were 2 failures:
1) Given User opens "facebookURL" on "ChromeBr"(Scenario: Open FB)
java.lang.IllegalStateException: The driver executable does not exist: C:\Users\
PC\Downloads\chromedriver.exe
        at com.google.common.base.Preconditions.checkState(Preconditions.java:53
4)
        at org.openqa.selenium.remote.service.DriverService.checkExecutable(Driv
erService.java:136)
        at org.openqa.selenium.remote.service.DriverService.findExecutable(Drive
rService.java:131)
        at org.openqa.selenium.chrome.ChromeDriverService.access$000(ChromeDrive
rService.java:32)
        at org.openqa.selenium.chrome.ChromeDriverService$Builder.findDefaultExe
cutable(ChromeDriverService.java:137)
        at org.openqa.selenium.remote.service.DriverService$Builder.build(Driver
Service.java:329)
        at org.openqa.selenium.chrome.ChromeDriverService.createDefaultService(C
hromeDriverService.java:88)
        at org.openqa.selenium.chrome.ChromeDriver.<init>(ChromeDriver.java:124)

        at util.WebConnector.openBrowser(WebConnector.java:36)
        at stepDefinitions.Testing.user_opens_on(Testing.java:12)
        at ?.Given User opens "facebookURL" on "ChromeBr"(feature/Testing.featur
e:4)
2) Scenario: Open FB
java.lang.IllegalStateException: The driver executable does not exist: C:\Users\
PC\Downloads\chromedriver.exe
        at com.google.common.base.Preconditions.checkState(Preconditions.java:53
4)
        at org.openqa.selenium.remote.service.DriverService.checkExecutable(Driv
erService.java:136)
        at org.openqa.selenium.remote.service.DriverService.findExecutable(Drive
rService.java:131)
        at org.openqa.selenium.chrome.ChromeDriverService.access$000(ChromeDrive
rService.java:32)
        at org.openqa.selenium.chrome.ChromeDriverService$Builder.findDefaultExe
cutable(ChromeDriverService.java:137)
        at org.openqa.selenium.remote.service.DriverService$Builder.build(Driver
Service.java:329)
        at org.openqa.selenium.chrome.ChromeDriverService.createDefaultService(C
hromeDriverService.java:88)
        at org.openqa.selenium.chrome.ChromeDriver.<init>(ChromeDriver.java:124)

        at util.WebConnector.openBrowser(WebConnector.java:36)
        at stepDefinitions.Testing.user_opens_on(Testing.java:12)
        at ?.Given User opens "facebookURL" on "ChromeBr"(feature/Testing.featur
e:4)

FAILURES!!!
Tests run: 2,  Failures: 2

I understand that it is trying to find the file and it is failing. When I open Jar, it is in the below structure.

Jar Structure after Exporting

How do I maintain the same folder structure so that I don't get File Not Found Exception or Is there any other way to run this successfully?

3条回答
倾城 Initia
2楼-- · 2019-08-21 04:41

My suggestion is, you can run the jar file using batch file.

First you can create jar file of your project by using maven build. Below are the steps

Right click on Maven project -> Run As -> Maven Build -> in target give clean package -> Run

After successful execution, jar file will be created in target folder of your project. Now create one batch file in your project location like run.bat. Below is the code you need to write in batch file

java -Xms512m -Xmx512m -jar execute.jar -0 true
pause

you can change jar name. Now go to batch file location and double click on it. Your project will execute and console report will be displayed in command prompt.

查看更多
祖国的老花朵
3楼-- · 2019-08-21 04:59

It is not a problem of the structure of jar, but it is about reading a location to find a file.

Assume you have a simple java file that have code code (pseudo) like below:

  1. Get current directory
  2. Look for sub directory named src/test/java/config in this current directory
  3. throw an exception if directory is not found.

Now if you are running the Main class from your IDE (eclipse), you do have "src" folder and all required sub folders. Hence there won't be an exception.

But if you create a jar, and place the jar in a different "new folder" (jarFolder e.g), then when you will run the code, you will see the exception directory not found. That is obvious.

So it is upto you, and only you to follow which approach you want.

1) Some ship the properties/config file with the jar (least recommended when the content of config file is dynamic and needs to be changed.)

2) Some keep their config files under just config layer and then wherever you copy a jar, create a config folder and put config file there. In that case you may have to read it like

System.getProperty("user.dir")+File.separator+"config"+File.separator+"config.properties"; // Offcourse, using \\ is a bad way to use File.separtor as it will not work on unix again

3) Another thing, I would suggest is that people don't shop their "src" but ship their binaries which normally reside it in classes folder, not in src folder. So putting anything from src folder in binary jar shall be avoided.

查看更多
贪生不怕死
4楼-- · 2019-08-21 05:03

We cannot maintain the same structure of the project. Best solution, I have found is, while running executable jar from anyother path, I made sure that those folders(which are not part of jar but a part of project) exists in the same path where my executable jar is.

查看更多
登录 后发表回答