By Developers, For Developers

Historical errata for The Cucumber for Java Book

PDF PgPaper PgTypeDescriptionFixed onComments
7TYPO

Cucumber misspelled, Groovy misspelled.

2014-09-16Thanks
19ERROR

Twice in last paragraph on pg 19 you refer to a method’s local variable as an instance variable. It is wrong to refer to a local variable as instance variables.

You state:
“All we’ve done here is store the input from the feature in an instance variable.”

and see code in the link first_taste/05/step_definitions/CheckoutSteps.java

bananaPrice is not defined as an instance variable. There are no instance variables in that code. The variable is local to the method.

2014-09-16Good spot - the code had changed since the text was written. I've just removed that paragraph.
13SUGGEST

Cucmber’s output is highlighted with colors that do not display accurately in Windows which displays control characters like ‘33m’ instead of colors, for instance:
←[33mU←[0m←[33mU←[0m←[33mU←[0m
1 Scenarios (←[33m1 undefined←[0m)
3 Steps (←[33m3 undefined←[0m)

The cucumber wiki addresses colors for Windows in the Console-Colours portion of the wiki.

I installed ANSICON as suggested including adding it to the PATH in my command window and then running ANSICON. This corrected the display of colors in Cucumber’s output

2014-09-16I've made a few edits to make the chapter First Taste more friendly to Windows users, including a sidebar that covers the control characters. Ansicon will be convered in the appendix "Installing"
49OK

In the section “Creating a Step Definition”, in the second paragraph (ignoring the @Given code fragment) which starts You’ll typically put several step definitions like“…, the paragraph ends with a missing cross ref which reads: ”see the (as yet)
unwritten sec.finding-step-defsI don’t know how to generate a cross reference to sec.findingstep-
defs)"

In the epub this missing ref reads "missing cross reference target…))

2014-10-02This section is in the (as yet unpublished) chapter Controlling Cucumber. The cross reference will come good when that gets released
128TYPO

Given(“^I request \\\\$(\\\\d+)$”) should be When(“^I request \\\\$(\\\\d+)$”)

2014-10-17
127SUGGEST

It talks about moving the $ into the capture group within the @Given annotation but it doesn’t mention anything about updating the MoneyConverter class.

There probably should be code showing the fix to the MoneyConverter class even if most readers would figure out the problem.

2014-10-27
144TYPO

“Run ./cucumber now to see whether we have it trapped” should be “Run mvn clean test now to see whether we have it trapped”

2014-10-17
145SUGGEST

The sample code shows adding the debit method to account and says that it’s fixed. However, it doesn’t mention adding the minus method to the Money class. Maybe I missed that being implemented in a different chapter but I didn’t see it as I was going through the book. I think the code to add minus to the Money class should be added just to keep the flow of the book consistent(the bookstops at pretty much every compilation error and shows the solution).

2014-11-16Rather than talk about adding the minus() method, I've just gone back and added it from the beginning.
153TYPO

Given(“$I withdraw \\\\$(\\\\d+)$”) should be When(“$I withdraw \\\\$(\\\\d+)$”)

2014-10-17
153SUGGEST

The parameters for the withdrawFrom method change from “int dollars” to “int amount”. It was pretty subtle and made it weird when I started following the code when implementing the AtmUserInterface class a couple pages later (my code still was using the dollars parameter and the code in the book was updated with the amount parameter…so for a minute I was wondering where did this amount parameter come from). Maybe mention the parameter name change or just keep the parameter names the same to make following the code flow a bit better.

2014-10-27
156TYPO

The code on the previous page for AtmUserInterface uses the FirefoxDriver but the pom.xml adds a dependency to the chrome driver. I wasn’t sure which driver to use so I stuck with trying to use the ChromeDriver. Also, running the test using the driver doesn’t work. I’m getting a timeout error where it’s trying to talk to a service running on a random port on the local machine to get a status or something like that. Not sure what that is since I’m not really familiar with Selenium.

2014-10-17I've removed the dependency on ChromeDriver, which was a spurious remnant of a previous version. \n \nMore information about the timeout would be appreciated - I can't replicate.
156SUGGEST

The note from Seb mentions checking browser and selenium driver versions if there are error messages being displayed. It would be nice if the book mentioned what selenium driver version and browser version they used so the reader could try to download those and follow with that instead of spending time trying to find out how to get selenium to work.

2014-11-16
158TYPO

The code Before public void logInAsAdmin(“admin”) {…} should be Before(“admin”) public void logInAsAdmin() {…}

2014-10-17
162ERROR

When running the test with jetty server startup configuration, the test just hangs. I had to removed the server.join() call in the AtmServer start method and the test started working again. I’m not sure why that was the case.

2014-10-17
163TYPO

The ids for the input and button elements (amount and withdraw) in the AtmServlet code do not match what the AtmUserInterface was previously written with the web driver (Amount and Withdraw…both capitalized)

2014-10-17
167TYPO

“We covered the basics of Webbit applications” I think should be “We covered the basics of web applications”.

2014-10-17
179TYPO

“public void stopServer()” should probably be “public void stopBackgroundThread()”

2014-10-17
189TYPO

class Account implements Model should be class Account extends Model

page 383 in epub for iBooks

2014-10-17
383 TYPO

class Account implements Model should be class Account extends Model

2014-10-17
394SUGGEST

Tries to run mvn clean test but doesn’t say anything about setting up mysql locally. Now, it took me awhile googling all the things needed download mysql, setup the teller user, grant access to teller, and create the db. And now that I know, doing it again would be trivial. However, I think it would be nice to have those instructions so that readers won’t spend a hour or so trying to figure out how to set up MySQL correctly

page is from epub version

2014-11-16
416 ERROR

forgot to mention removing the call to Base.rollbackTransaction() in reset hooks. The scenario will fail because of the trying to rollback a transaction when using truncation instead for clearing DB state.

2014-10-17
46TYPO

we’ve been running >Cucmber< using

2015-01-21
47SUGGEST

in order to have maven execute the tests, I found I needed to add a small Java class like the code below; you mention it later but I think you need it here so that readers can code and run along:

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

@RunWith(Cucumber.class)
public class RunCucumberTest {
}

A class like that is only needed to run the tests via JUnit. This part of the book is using Cucumber's CLI to find & execute the scenarios, so this class is not needed.... yet. We need it when we start using Maven/Junit in a few chapters time
145TYPO

In the step below we’re still withdrawing int-dollars, not Money which the teller doesn’t understand yet:

@When(“^I withdraw \\\\$(\\\\d+)$”)
public void iWithdraw$(Money amount) throws Throwable {
Teller teller = new Teller();
teller.withdrawFrom(myAccount, amount);
}
Try it. It works!

2015-01-26
145ERROR

[…] Let’s see whether we’ve managed to fix the bug:
…. <<< I think you meant to insert a mvn clean test run here

Hooray, we did it!

2015-01-26
159145ERROR

(I mixed up pdf and book page numbers in the erratum, this one’s right:)

[…] Let’s see whether we’ve managed to fix the bug:
…. <<< I think you meant to insert a mvn clean test run here

Hooray, we did it!

2015-01-26
181TYPO

… the surface of it’s functionality => its

2015-01-21
238TYPO

Choose a DI container and browse it’s documentation
==> its

2015-01-21
238TYPO

Choose a DI container and browse it’s documentation
// typo: its

2015-01-21
120ERROR

Given("^I have been paid 50 dollars$"/ do") will not work in Java Given(“^I have been paid$”/ do") will not work in Java

2015-01-26
7TYPO

Where :
In the first example of acceptance test, Scenario#2 (Duplicate email)

What :
1. The description says “Where someone tries to create…”
I think it should be “When someone tries to create…”

2. The “When” statement says “I sign up with an email address that has already registered”
I think it should be “I sign up with an email address that is already registered”.

11TYPO

Where: Chapter 2, section “Understanding Our Goal”, paragraph 2.

What: The paragraph says : “We have an incredible vision of what this checkout will one day power: a
traditional checkout till, a portable scanner that you carry around while you shop,…”

Something is not right here : “a traditional checkout till”

132TYPO

In the $ShouldBeDispensed method at the top of the page the code contains
helper.getCashSlot().contents()
but in the definition of the CashSlot class at the bottom of the page and on page 134 the method is called getContents.

53TYPO

In the Character Classes section, the first code sample contains \\\\$([01234567890]*) as the regex. I don’t believe you need the 0 at the start and the end of the list of digits.

2911TYPO

The footnote for installing the cucumber jvm now points to a dead link. Going to the link at the bottom of the page that I cannot include here redirects to a 404 error page

161ERROR

Hope you can help. Not sure if this is a technical error or not. After updating AtmUserInterface.java, then I get a compile error. Detail below. Are you able to help. Please email me at wsinclair@indigocube.co.za for full description:

java.lang.Error: Unresolved compilation problem:
\tThe constructor AtmUserInterface(EventFiringWebDriver) is undefined

\tat support.KnowsTheDomain.getTeller(KnowsTheDomain.java:34)
\tat nicebank.TellerSteps.iWithdraw$(TellerSteps.java:28)
\tat ?.When I withdraw $20(C:/Users/wsinclair/workspace/Eclipse/Maven/MavenCucumberPrototype/src/test/resource/cash_withdrawal.feature:4)

Here is knowsTheDomain
————————————
/*
* Excerpted from “The Cucumber for Java Book”,
* published by The Pragmatic Bookshelf.
* Copyrights apply to this code. It may not be used to create training material,
* courses, books, articles, and the like. Contact us if you are in doubt.
* We make no guarantees that this code is fit for any purpose.
* Visit (hyperlinks not allowed
*/
package support;

import nicebank.Account;
import nicebank.CashSlot;
import nicebank.Teller;

import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.support.events.EventFiringWebDriver;

public class KnowsTheDomain {
private Account myAccount;
private Teller teller;
private CashSlot cashSlot;
private EventFiringWebDriver webDriver;

public Account getMyAccount() {
if (myAccount == null){
myAccount = new Account();
}

return myAccount;
}

public Teller getTeller() {
if (teller == null){
teller = new AtmUserInterface(getWebDriver());
}

return teller;
}

public CashSlot getCashSlot() {
if (cashSlot == null){
cashSlot = new CashSlot();
}

return cashSlot;
}

public EventFiringWebDriver getWebDriver() {
if (webDriver == null){
webDriver = new EventFiringWebDriver(new FirefoxDriver());
}

return webDriver;
}
}

Here is ATMUserInterface

/*
* Excerpted from “The Cucumber for Java Book”,
* published by The Pragmatic Bookshelf.
* Copyrights apply to this code. It may not be used to create training material,
* courses, books, articles, and the like. Contact us if you are in doubt.
* We make no guarantees that this code is fit for any purpose.
* Visit Hyperlinks not allowed
*/
package support;

import org.openqa.selenium.By;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.support.events.EventFiringWebDriver;
import org.openqa.selenium.WebDriverException;

import cucumber.api.java.After;
import cucumber.api.Scenario;

import nicebank.Account;
import nicebank.Teller;

import hooks.ServerHooks;

class AtmUserInterface implements Teller {

private final EventFiringWebDriver webDriver;

public AtmUserInterface(){
this.webDriver = new EventFiringWebDriver(new FirefoxDriver());
}

public void withdrawFrom(Account account, int dollars) {
try {
webDriver.get(“hyperlink not allowed” + ServerHooks.PORT);
webDriver.findElement(By.id(“Amount”))
.sendKeys(String.valueOf(dollars));
webDriver.findElement(By.id(“Withdraw”)).click();
}
finally {
webDriver.close();
}
}
}

130TYPO

It is said that the method:
When("^I withdraw \\\\$(\\\\d+)$") public void iWithdraw$(Money amount) throws Throwable { Teller teller = new Teller(); teller.withdrawFrom(myAccount, amount); } Try it. It works! But, teller.withdrawFrom() method accepts Account instance and int of dollars. So it can't even compile at that moment. More of that, no Tranformer is applied to be able to transforme teh matched value into Money object. If we continue, we'll see on page 131 the correct step declaration: When(“^I withdraw \\\\$(\\\\d+)$”)
public void iWithdraw$(int dollars) throws Throwable {
Teller teller = new Teller();
teller.withdrawFrom(helper.getMyAccount(), dollars);
}.

132ERROR

in the step method definition it should be:
helper.getCashSlot().getContents());

instead of

helper.getCashSlot().contents());

150ERROR

In AtmServer constructor, the server instance is initialized with hard-coded port value instead of taking it from the passed in parameter:
server = new Server(9988);

130ERROR

At the top of the page, it says:

@When(“^I withdraw \\\\$(\\\\d+)$”)
public void iWithdraw$(int dollars) throws Throwable {
Teller teller = new Teller();
teller.withdrawFrom(helper.getMyAccount(), dollars);
}
Try it. It works!

This code uses an instance of the helper class from the next section, but we haven’t even written it yet. At this point it should just use the instance variable “myAccount” when passing the account into the teller.withdrawFrom() method.

90TYPO

Page 89 states to generate step definition snippets and paste them into step_definitions/BoardSteps.java however pdf page 90 lists the file path as tic_tac_toe and the code snippet lists package as tic_tac_toe. this leads the code to be run to result in undefined status. It would be best to keep this in sync with earlier examples and keep this as step_definitions.

155TYPO

When searching the element by ID, it should be in lower case:
webDriver.findElement(By.id(“amount”)) instead of
webDriver.findElement(By.id(“Amount”)). In the supplied code source (see support code, 17 it is correct). The same should be applied to webDriver.findElement(By.id(“Withdraw”)).click();

49ERROR

In nearly every sample project that I build using maven, I get an error “annotations are not supported in -source 1.3”. The error is always solved by adding this to my pom section:

maven-compiler-plugin
2.3.2

1.6
1.6

Maybe you would consider updating the sample code. It’s possible I did not set up my maven correctly. But no instructions from the maven project or stack-overflow could solve it without adding a section to the pom file. BTW, I am using java version “1.7.0_91”.

Thanks,

Dave

269TYPO

This is in Chapter 14.
Maven main class package name has a typo.

It should be cucumber.api.cli.Main

It is currently cucumber.cli.Main

4442ERROR

in ‘Using Hooks’ section, the book indicates to create a Hook class, but forgots to mention that we need to create that class in the glue package we specify when running cucumber scenario so the class can be found.

156ERROR

Chapter 8. Support Code: Using Hooks: No mention is made of the fact that hook classes must be in the package tree defined by the Cucumber glue option. Place them anywhere else, and they won’t run.

173ERROR

The finish() method listed uses a variable named “helper”. The text does not tell the reader what type “helper” is nor how to initialize it.

172ERROR

The mvn clean test suggested on this page will not result, as claimed, in an image of the greeting page being saved. Instead the image will be blank. This is because AtmUserInterface instantiates its own EventFiringWebDriver. That results in a browser window being opened twice, the second one not addressing the greeting page (assuming you’ve already fixed AtmServer).

Fixing this requires altering AtmUserInterface’s constructor to take an EventFiringWebDriver as an argument and initialize its webDriver field with it, and altering KnowsTheDomain to supply that EventFiringWebDriver.

175ERROR

Apologies, wrong PDF page number on the prior submission…

The mvn clean test suggested on this page will not result, as claimed, in an image of the greeting page being saved. Instead the image will be blank. This is because AtmUserInterface instantiates its own EventFiringWebDriver. That results in a browser window being opened twice, the second one not addressing the greeting page (assuming you’ve already fixed AtmServer).

Fixing this requires altering AtmUserInterface’s constructor to take an EventFiringWebDriver as an argument and initialize its webDriver field with it, and altering KnowsTheDomain to supply that EventFiringWebDriver.

174ERROR

For some reason the wrong PDF page number keeps showing up in the errata… Anyway, here goes one more time, with feeling:

The mvn clean test suggested on this page will not result, as claimed, in an image of the greeting page being saved. Instead the image will be blank. This is because AtmUserInterface instantiates its own EventFiringWebDriver. That results in a browser window being opened twice, the second one not addressing the greeting page (assuming you’ve already fixed AtmServer).

Fixing this requires altering AtmUserInterface’s constructor to take an EventFiringWebDriver as an argument and initialize its webDriver field with it, and altering KnowsTheDomain to supply that EventFiringWebDriver.

56TYPO

First paragraph reads “That word is then passed to the method we named accountType in the second argument.” I believe you mean “That word is then passed to the iHaveDeposited$InMyAccount method in the second argument.”

20TYPO

The link for footnote #3 goes to Pragmatic Bookshelf site with “No title for ‘sjrcuc’.” error. Link should be “srjcuc” instead of “sjrcuc” (‘r’ and ‘j’ are transposed).

13ERROR

Not possible to execute cucumber as described:

-rwxrw-r— 1 ejner ejner 335723 Aug 29 22:41 cucumber-core-2.0.0.jar*
-rwxrw-r— 1 ejner ejner 300451 Aug 29 22:41 cucumber-java-2.0.0.jar*
-rwxrw-r— 1 ejner ejner 596141 Aug 29 22:41 cucumber-jvm-deps-1.0.6.jar*
-rwxrw-r— 1 ejner ejner 341931 Aug 29 22:41 gherkin-4.1.3.jar*
ejner@ejner-GGS-Petit-Deluxe:~/tmp/cucumber/jars$ java -cp “*.jar” cucumber.api.cli.Main -p pretty .
Error: Could not find or load main class cucumber.api.cli.Main

Also I tried Maven dependencies on those 4 artifacts, but always run into error

ejner@ejner-GGS-Petit-Deluxe:~/.m2/repository/io/cucumber$ java -cp “cucumber-jvm/2.0.0/:tag-expressions/1.0.1/:gherkin-jvm-deps/1.0.4/:cucumber-jvm-deps/1.0.6/:cucumber-java/2.0.0/:gherkin/4.1.3/:cucumber-core/2.0.0/” cucumber.api.cli.Main -p pretty .
Exception in thread “main” cucumber.runtime.CucumberException: No backends were found. Please make sure you have a backend module on your CLASSPATH.
\tat cucumber.runtime.Runtime.(Runtime.java:56)
\tat cucumber.runtime.Runtime.(Runtime.java:45)
\tat cucumber.runtime.Runtime.(Runtime.java:41)
\tat cucumber.api.cli.Main.run(Main.java:35)
\tat cucumber.api.cli.Main.main(Main.java:18)

13SUGGEST

There is a project on GitHub

cucumber/cucumber-java-skeleton

which worked for me, by running build.xml,
instead of the instructions in the book, which I could not get to work.

162SUGGEST

At the top of the page, when you say “We have to share the same instance of the Selenium web driver between WebDriverHooks and AtmUserInterface”, I suggest that also you point out the need then to remove the webDriver.close(); call from AtmUserInterface.java. Leaving that line there will cause an error when trying to take the screenshot since the WebDriverHooks.java would try to use the webDriver that is now closed.

134ERROR

@When(“^I withdraw \\\\$\\\\d+)$”)
public void iWithdraw$(int dollars) throws Throwable {
helper.getTeller().withdrawFrom(helper.getMyAccount(), dollars);
}

This throws an NPE because a cashSlot has not been instantiated yet. Quickest solution is to insert helper.getCashSlot(); before the helper.getTeller() ………

76ERROR

The class of cucumber.api.DataTable has been changed over to io.cucumber.datatable.DataTable. With this change, the raw method no longer exists. The expressive scenarios from folder 02 on will be taking in a List<List>, trying to convert it to a raw table, and then using the values for processing, which is no longer possible.

Was able to achieve the same results from page 77’s excercise using DataTable board instead of List<List>, then setting board equal to table.transpose()

Categories: