Karate v0.7.0 Release Notes

Release Date: 2018-02-19 // about 6 years ago
  • ๐Ÿš€ > This guide assumes you are upgrading from 0.6.2, please refer to older release notes if needed.

    ๐Ÿš€ Karate has had a re-vamp of the JavaScript evaluation engine, which improves execution performance by more than 50%. And Karate has expanded into the area of API test-doubles. Karate is also now available as a single binary (see the link at the top of these release notes), which is useful for starting a mock-server, demos or exploratory testing.

    In the process, some significant additions have been made to Karate's syntax plus a couple of carefully considered changes. The good news is that we estimate 80% of existing users will NOT face any issues. Even if you do run into breaking changes - you can breathe easy, as the fixes are very simple and likely to be addition of a single character, or at the most - a single line.

    ๐Ÿš€ Important: Please do provide feedback if you run into any other issues ! Note that a good way to keep up to date with releases and other news is to follow us on Twitter @KarateDSL.

    ๐Ÿ’ฅ Breaking Changes

    (1) You need to be on a Java version at least 1.8.0_112 or greater

    This should not be an issue for most teams and it is quite likely that you are already on a recent enough version. But do check, and the problem that you can run into will look like this:

    java.lang.RuntimeException: evaluation of karate-config.js failed:
        at com.intuit.karate.ScriptContext.<init>(ScriptContext.java:150)
            ...
        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        
    

    โœ… Short Fix Description : Upgrade to the latest version of the Java 8 JRE.

    0๏ธโƒฃ (2) Karate Expressions Default to JS

    ๐Ÿ›  And JsonPath (or XPath) that refers to a variable other than response needs to be pre-fixed with $ on the RHS

    Karate used to attempt to 'auto-detect' JsonPath (and XPath) on the Right-Hand-Side of Karate Expressions. For example this used to work:

    \* def foo = bar[\*].id
    

    This had some non-ideal consequences, for example if you wanted to get the length of bar, you would have to 'force' JavaScript evaluation, by wrapping in parentheses:

    \* def len = (bar.length)
    

    Now, Karate 'defaults' to always expecting JS on the R.H.S. This has multiple advantages, there is no more 'guesswork' and trial-and-error needed, and the parsing logic became simpler and runs faster. So the above two lines can be now written like this. Prefxing a variable with $ tells Karate to use JsonPath instead of JS:

    \* def foo = $bar[\*].id\* def len = bar.length
    

    Note that $ still represents the response and JsonPath in the form $.foo will continue to work like always.

    Similarly for XML, / still represents the response. You will need to use the $varname form for XPath on a variable which is not the response, like so:

    \* def documentId = $myXml/root/EntityId
    

    Note that there is no change to the get syntax. Just that $varname[*].id is now an alternative to get varname[*].id.

    โœ… Short Fix Description : All you need to do is prefix a $ where necessary.

    (3) #null is stricter, key must be present

    Karate used to treat all the following as 'equal' when doing a match.

    • {}
    • { foo: null }
    • { foo: '#null' }

    Not any more. So if you were using #null and you want to match even when the key is not present, just use the 'optional null' marker.

    \* def test = {}\* match test == { foo: '##null' }
    

    Note that #present and #notpresent have been newly introduced and take care of all the possibilities.

    โœ… Short Fix Description : All you need to do is prefix a # where necessary or use '##null' instead of an expected null or just use #ignore.

    (4) call will not re-use or "share" variables

    There was a bug in the implementation of call where variables could be over-written by the 'called' routine even when not using 'shared scope'. The most likely situation where you may run into issues is when:

    • ๐Ÿ”ง you are using configure headers with a JS function in your 'main' feature
    • the JS function depends on the value of a context variable (typically using karate.get())
    • you attempt to set the value of this variable in the 'called' feature - which will not be 'seen' by the JS function because it is executing in a different 'sandbox' (of the parent / caller)
    • you make an HTTP request in the 'called' feature that depends on the JS function working correctly, typically when you do more than one call as part of an authentication flow

    ๐Ÿ“š If you had faithfully followed the 'sign-in' example in the main Karate documentation, you might have this issue and the documentation has been updated to make clear what the 'right thing to do' is. Just refer to the table at the end of the section on shared scope.

    โœ… Short Fix Description : Either duplicate the configure headers line in the 'called' feature (easy fix), or switch to using shared scope (recommended).

    0๏ธโƒฃ (5) Karate will send charset=utf-8 in the request Content-Type header by default

    ๐Ÿ”ง This is expected to be the intent almost all the time. You can over-ride this per-request by setting the header, for example * header Content-Type = 'application/xml;charset=ISO-8859-15'. To set the request charset 'globally', use the configure charset keyword.

    ๐Ÿ”ง In rare cases, the server may be unable to handle a charset appearing in the Content-Type header, and we encountered this once when the entity happened to be part of a multipart request. This actually can be considered as a bug in the server but you can work around this case by setting * configure charset = null before the HTTP request is made.

    โœ… Short Fix Description : Set * configure charset = null only if you run into a situation where the server doesn't like a charset appearing in the Content-Type header (which should ideally be fixed on the server).

    ๐Ÿ”Œ (6) Cucumber native plugins if specified for the JUnit runner will be ignored

    ๐Ÿ‘ท Most users will not be impacted by this. But if you use something like @CucumberOptions(plugin = {"pretty", "json:target/cucumber/cucumber-data"}) in conjunction with the JUnit runner, the value of plugin (or format) if specified will be ignored. With Karate, all you need is either the parallel runner (which emits the JUnit XML and the Cucumber standard JSON which most CI and third-party reporting tools can consume) or the HTML report.

    โœ… Short Fix Description : If you were relying on JSON like in the example above, switch to the parallel runner, which is more suited for API tests. Else you don't need to change anything, and the value of plugin will be silently ignored.

    ๐Ÿ›  Notable Enhancements and Fixes

    • ๐Ÿ‘ #255 custom version string should be supported in the Content-Type header
    • ๐Ÿ›  #256 non-json non-string fuzzy match does not work (fixed)
    • ๐Ÿ“‡ #257 Karate now supports afterScenario and afterFeature 'hooks', and you can get access to test metadata such as the feature file name and scenario name via karate.info
    • โœ… #259 Malformed JSON response stops test with error (fixed)
    • ๐Ÿ“œ #260 XML with DTD still does not parse correctly (fixed)
    • ---- Introduced the copy keyword
    • ---- Introduced the eval keyword
    • โœ๏ธ #262 syntax failures and typos now will fail scenario
    • ๐Ÿ›  #267 result of karate.read() of JSON within a JS function would not 'cross over' (fixed)
    • #273 option to run a global one-time init routine, especially useful for auth karate.callSingle()
    • #281 you can now (optionally) use a specified certificate for HTTPS / mutual authentication, thanks to @mattjm for the PR
    • #282 NPE when first Scenario is Outline in 0.6.2
    • ---- Parallel reporter now summarizes error messages at the end of a test-run making it much easier to troubleshoot a large suite if you only have access to the console log
    • ๐Ÿ‘ #298 Empty string supported as the Content-Type header (only supported in Apache)
    • #300 Combination of form-field and header would re-set headers
    • ๐Ÿ‘€ ---- Introduced configure charset which defaults to utf-8 so existing tests should work un-changed, also see #302
    • ๐Ÿ’ป #306 Improved JavaFX UI, thanks to @RavinderSinghMaan for the PR
    • #309 Introduced match contains any
    • #311 Improved JUnit dev-mode report, thanks to @athityakumar for the PR