質問

Let's say I have the following classpath definition in a FitNesse suite:

!*> '''Classpath'''
!path /home/stewart/white space test/example-1.0.0-SNAPSHOT/target/test-classes
!path /home/stewart/white space test/example-1.0.0-SNAPSHOT/target/classes
!path /home/stewart/.m2/repository/org/fitnesse/fitnesse/20121220/fitnesse-20121220.jar
*!

I have tried the following forms of quoting or escaping:

  • Vanilla whitespace: !path /home/stewart/white space test/example-1.0.0-SNAPSHOT/target/classes
  • Backslash: !path /home/stewart/white\ space\ test/example-1.0.0-SNAPSHOT/target/classes
  • Double backslash: !path /home/stewart/white\\ space\\ test/example-1.0.0-SNAPSHOT/target/classes
  • Double quotes: !path "/home/stewart/white space test/example-1.0.0-SNAPSHOT/target/classes"
  • Single quotes: !path '/home/stewart/white space test/example-1.0.0-SNAPSHOT/target/classes'
  • % encoding: !path /home/stewart/white%20space%20test/example-1.0.0-SNAPSHOT/target/classes
  • Using +'s: !path /home/stewart/white+space+test/example-1.0.0-SNAPSHOT/target/classes
  • Unicode sequence: !path /home/stewart/white\u0020space\u0020test/example-1.0.0-SNAPSHOT/target/classes
  • Unicode sequence with extra backslash: !path /home/stewart/white\\u0020space\\u0020test/example-1.0.0-SNAPSHOT/target/classes
  • Wildcards: !path /home/stewart/white*space*test/example-1.0.0-SNAPSHOT/target/classes
  • FitNesse wiki escaping: !path !-/home/stewart/white space test/example-1.0.0-SNAPSHOT/target/classes-!

With vanilla whitespace and some of the quoted whitespaces, the tests don't run at all and I get the error:

Could not find or load main class space

According to the error logs, FitNesse is attempting to escape the whitespace with quotes. It's invoking the FitServer with this command:

java -cp fitnesse.jar:"/home/stewart/white space test/example-1.0.0-SNAPSHOT/target/test-classes":"/home/stewart/white space test/example-1.0.0-SNAPSHOT/target/classes":/home/stewart/.m2/repository/org/fitnesse/fitnesse/20121220/fitnesse-20121220.jar fit.FitServer linux-desktop 9123 10

With some of the escaping the tests do run, but they fail because FitNesse cannot find the fixtures on the classpath, which I believe means that the substitute for the whitespace (+, %20, \u0020, etc) is not getting resolved as whitespace, but as a path literal.

I'm beginning to think that it's not possible to do this in FitNesse ...


Update: I also tried experimenting with the COMMAND_PATTERN and CLASSPATH_PROPERTY FitNesse variables, as detailed in the documentation about customizing test execution


FitNesse version is 20121220.

役に立ちましたか?

解決

Ok, so the first thing to note is that this phenomena does not happen on Windows. FitNesse automatically encloses classpath elements contained whitespace with double-quotes, as already noted in the question. The command which FitNesse generates is:

java -cp fitnesse.jar:"/home/stewart/white space test/example-1.0.0-SNAPSHOT/target/test-classes":"/home/stewart/white space test/example-1.0.0-SNAPSHOT/target/classes":/home/stewart/.m2/repository/org/fitnesse/fitnesse/20121220/fitnesse-20121220.jar fit.FitServer linux-desktop 9123 10

On Windows, this would be:

java -cp fitnesse.jar:"C:\white space test\example-1.0.0-SNAPSHOT\target\test-classes":"C:\white space test\example-1.0.0-SNAPSHOT\target\classes":C:\.m2\repository\org\fitnesse\fitnesse\20121220\fitnesse-20121220.jar fit.FitServer windows-desktop 9123 10

And it just works!

Given that Windows is the operating system where it's common to have whitespace in directory (folder) names, I could have stopped there; but I wanted to dig deeper, as you can occasionally get whitespace in directory names on Unix-like systems (MacOS springs to mind.)

Digging into FitNesse source code, the class we are interested in is fitnesse.testsystems.CommandRunner. In the method asynchronousStart() it uses Java's Runtime.exec() method.

Runtime.exec() has overloaded methods. In some, the command is a String which gets parsed with a java.util.StringTokenizer. In others, the command is already a String[] and does not get further parsed.

In other words, this fails:

String cmd = "java -cp fitnesse.jar:\"/home/stewart/white space test/example-1.0.0-SNAPSHOT/target/test-classes\":\"/home/stewart/white space test/example-1.0.0-SNAPSHOT/target/classes\":/home/stewart/.m2/repository/org/fitnesse/fitnesse/20121220/fitnesse-20121220.jar fit.FitServer linux-desktop 9123 10";
String[] env = new String[]{};
Runtime.getRuntime().exec(cmd, env);

Whilst this works:

String[] cmd = new String[] {
    "java",
    "-cp",
    "fitnesse.jar:\"/home/stewart/white space test/example-1.0.0-SNAPSHOT/target/test-classes\":\"/home/stewart/white space test/example-1.0.0-SNAPSHOT/target/classes\":/home/stewart/.m2/repository/org/fitnesse/fitnesse/20121220/fitnesse-20121220.jar",
    "fit.FitServer",
    "linux-desktop",
    "9123",
    "10";
};
String[] env = new String[]{};
Runtime.getRuntime().exec(cmd, env);

Conclusion: it's a bug in FitNesse.


Update: this is fixed FitNesse versions 20140623 onwards.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top