Karate: NPE when first Scenario is Outline in 0.6.2

Created on 12 Jan 2018  路  8Comments  路  Source: intuit/karate

If the first Scenario when running the entire test suite is a "Scenario Outline", I get a NPE. If I put a dummy scenario before the outline (or if another feature file runs first), it works fine. This is only affecting 0.6.2 (earlier versions, including 0.6.1, work fine).

Does not work:

Feature: authenticate failure

  Background:

    * url urlBase

  Scenario Outline: authenticate invalid user with missing or wrong credentials

    Given path 'auth'
    And request { username: '<username>', password: '<password>' }
    When method post
    Then status 200
    And match response contains { user: '#null', token: '#null', error: '#string' }

    Examples:

    | username            | password            |
    | #(username)         | #(password)         | 
    | #(username)         | test-wrong-password |
    | test-wrong-username | test-wrong-password |
    | #(username)         | #(password)         | 
    |                     |                     |

I get failed tests and this NPE:

java.lang.NullPointerException
    at com.intuit.karate.junit4.Karate$1.step(Karate.java:84)
    at cucumber.runtime.model.StepContainer.format(StepContainer.java:33)
    at cucumber.runtime.model.CucumberScenarioOutline.formatOutlineScenario(CucumberScenarioOutline.java:52)
    at cucumber.runtime.junit.ScenarioOutlineRunner.run(ScenarioOutlineRunner.java:52)
    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 com.intuit.karate.junit4.Karate.runChild(Karate.java:118)
    at com.intuit.karate.junit4.Karate.runChild(Karate.java:33)
    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 com.intuit.karate.junit4.Karate.run(Karate.java:127)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
    at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)

However, when I force a simple feature to run before the Outline, it works fine:

Feature: authenticate failure

  Background:

    * url urlBase

  Scenario: dummy scenario before outline
    Given path 'missing'
    When method get
    Then status 404

  Scenario Outline: authenticate invalid user with missing or wrong credentials

    Given path 'auth'
    And request { username: '<username>', password: '<password>' }
    When method post
    Then status 200
    And match response contains { user: '#null', token: '#null', error: '#string' }

    Examples:

    | username            | password            |
    | #(username)         | #(password)         | 
    | #(username)         | test-wrong-password |
    | test-wrong-username | test-wrong-password |
    | #(username)         | #(password)         | 
    |                     |                     |

I am using IntelliJ with a JUnit run configuration.

bug fixed

Most helpful comment

@petercuffari hmm, can you let me know the exact JRE version you are on (output of java -version)

I've been trying to track down why this changed from previous versions.

And if you don't mind can you upgrade your JRE to a version greater than or equal to 1.8.0_112 and that should fix this.

All 8 comments

Yes. It would be great if you can confirm this is fixed in 0.7.0.RC3 which is available. Here's the upgrade guide: https://github.com/intuit/karate/wiki/Upgrading-To-0.7.0

and wow, I never realized this trick works ! thanks :)

| #(username)         | #(password)         | 

Thanks for the quick fix! I'm having trouble with 0.7.0.RC3. I get the following:

```13:20:15.247 [main] ERROR com.intuit.karate - javascript function call failed: ReferenceError: "karate" is not defined
13:20:15.247 [main] ERROR com.intuit.karate - failed function body: function() {
var env = karate.env; // get system property 'karate.env'
karate.log('karate.env system property was:', env);
if (!env) {
env = 'staging';
}
var config = {
env: env,
urlBase: 'https://foo.com',
username: 'user',
password: 'pass'
};
if (env == 'staging') {
config.urlBase = 'https://staging.foo.com';
}
return config;
}

java.lang.RuntimeException: evaluation of karate-config.js failed:

at com.intuit.karate.ScriptContext.<init>(ScriptContext.java:150)
at com.intuit.karate.StepDefs.<init>(StepDefs.java:78)
at com.intuit.karate.cucumber.KarateObjectFactory.getInstance(KarateObjectFactory.java:80)
at com.intuit.karate.cucumber.KarateObjectFactory.getStepDefs(KarateObjectFactory.java:87)
at com.intuit.karate.cucumber.KarateBackend.getStepDefs(KarateBackend.java:104)
at com.intuit.karate.cucumber.KarateBackend.getVars(KarateBackend.java:81)
at com.intuit.karate.cucumber.KarateBackend.afterStep(KarateBackend.java:89)
at com.intuit.karate.cucumber.CucumberUtils.afterStep(CucumberUtils.java:266)
at com.intuit.karate.cucumber.CucumberUtils.runStep(CucumberUtils.java:222)
at com.intuit.karate.cucumber.KarateRuntime.runStep(KarateRuntime.java:79)
at cucumber.runtime.model.StepContainer.runStep(StepContainer.java:44)
at cucumber.runtime.model.StepContainer.runSteps(StepContainer.java:39)
at cucumber.runtime.model.CucumberScenario.runBackground(CucumberScenario.java:59)
at cucumber.runtime.model.CucumberScenario.run(CucumberScenario.java:42)
at cucumber.runtime.junit.ExecutionUnitRunner.run(ExecutionUnitRunner.java: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 com.intuit.karate.junit4.Karate.runChild(Karate.java:127)
at com.intuit.karate.junit4.Karate.runChild(Karate.java:33)
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 com.intuit.karate.junit4.Karate.run(Karate.java:137)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)

Caused by: com.intuit.karate.exception.KarateException: javascript function call failed: ReferenceError: "karate" is not defined
at com.intuit.karate.Script.evalFunctionCall(Script.java:1569)
at com.intuit.karate.Script.call(Script.java:1520)
at com.intuit.karate.Script.callAndUpdateConfigAndAlsoVarsIfMapReturned(Script.java:1636)
at com.intuit.karate.ScriptContext.(ScriptContext.java:145)
... 37 more


What am I doing wrong?  I am setting the karate.env value with a java option of:

-ea -Dkarate.env=staging
```

Apologies if this is in the documentation somewhere!

@petercuffari hmm, can you let me know the exact JRE version you are on (output of java -version)

I've been trying to track down why this changed from previous versions.

And if you don't mind can you upgrade your JRE to a version greater than or equal to 1.8.0_112 and that should fix this.

Bingo!

I was on (mac):

java version "1.8.0_92"
Java(TM) SE Runtime Environment (build 1.8.0_92-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.92-b14, mixed mode)

I updated to 1.8.0_152 and it works now.

By the way, I really enjoy this project. Thank you for your work! And, my middle name is Thomas :)

@petercuffari thanks ! I will add the version requirement to the docs & upgrade guide.

I'll keep this issue open since the "final" 0.7.0 release is not out.

And, my middle name is Thomas :)

:thumbsup:

A work around is possible if you are stuck using an old version of Java.

Solution tested on:

java version "1.8.0_101"
Java(TM) SE Runtime Environment (build 1.8.0_101-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.101-b13, mixed mode)

The karate object is not defined at the time of parsing the config.

This means that any interaction with the karate object will cause the Javascript evaluation to fail.

i.e:

karate.configure('logPrettyResponse', true);

An example karate-config.js is:

function() {
  var serverUrl = karate.properties['server.url'];  
  if (!serverUrl) {
      serverUrl = 'localhost:8080';
  }
  var config = { // base config JSON
    moviesWebservice : 'http://' + serverUrl + '/movies-webservice/'
  };
  karate.configure('logPrettyResponse', true);
  return config;
}

Resulting in:

Caused by: com.intuit.karate.exception.KarateException: javascript function call failed: ReferenceError: "karate" is not defined

The karate object is defined at the time of the KarateFeature execution.

The solution is to remove all references to the karate object in karate-config.js

If you wanted to set a system property, you could do so via the Java interop:

function() {
  var System = Java.type('java.lang.System');   
  var serverUrl = System.getProperty("server.url");  
  if (!serverUrl) {
      serverUrl = 'localhost:8080';
  }
  var config = { // base config JSON
    moviesWebservice : 'http://' + serverUrl + ':8080/movies-webservice/'
  };
  return config;
}

Calling with the arguments: -Dserver.url=dev1.local, the above example will extract the system property.

If you want to access the karate object, you can do this in the feature Background:

Feature: Workaround for karate not being defined at time of parsing

  Background: 
    Given url moviesWebservice
    * def logsetup = karate.configure('logPrettyResponse', true) 

  Scenario: Get movies
    Given path 'movies'
    When method get
    Then status 200
Was this page helpful?
0 / 5 - 0 ratings

Related issues

bAmrish picture bAmrish  路  3Comments

76creates picture 76creates  路  3Comments

nuanyang233 picture nuanyang233  路  4Comments

ianrenauld picture ianrenauld  路  4Comments

bbchristians picture bbchristians  路  4Comments