Skip to content
This repository was archived by the owner on Apr 29, 2021. It is now read-only.

Pipe does not work in the test #10

Closed
roderik opened this issue May 26, 2013 · 8 comments
Closed

Pipe does not work in the test #10

roderik opened this issue May 26, 2013 · 8 comments

Comments

@roderik
Copy link

roderik commented May 26, 2013

Hello,

after seeing the screencast by @drnic i'm trying out bats in test-kitchen. But 'im having trouble with the most basic test

#!/usr/bin/env bats

@test "Test if GitHub is in the global ssh_known_hosts file" {
    run cat /etc/ssh/ssh_known_hosts | grep github
    [ "$status" -eq 0 ]
}

With | grep github -> failure
Without | grep github -> succes but this doesn't test what i want it to test
Running by hand exit value is 0

@hatchetation
Copy link

I hit the same thing, pipes don't appear to work, even if quoted.

If you're expecting a 0 exit code, you can forgo the run helper because BATS makes use of errexit:

@test "Test if GitHub is in the global ssh_known_hosts file" {
    cat /etc/ssh/ssh_known_hosts | grep github
}

Or, in my case, something slightly trickier -- testing for the absence of a string. BATS seems to be very good at catching errors in the pipe, despite my best efforts to exit 0.

e.g., this doesn't work:

@test "connection tracking / NAT shouldn't be enabled" {
     result=$(lsmod | grep -c nf_conntrack)
     [ $result -eq 0 ]
}

Workaround -- negate the exit code:

@test "connection tracking / NAT shouldn't be enabled" {
        ! lsmod | grep -q nf_conntrack
        [ $? -eq 0 ]
}

@spikegrobstein
Copy link

I ran into a similar problem, but my workaround was to do the following:

[[ ! $(some_command | grep some_value) ]]

obviously, it makes it very difficult to test for the exact return value

@spikegrobstein
Copy link

I've been dabbling with this and discovered another way to do your code:

lsmod | {
  run grep -q nf_contrack
  [ $status -ne 0 ]
}

That seems to do the trick and also feels a little better since it isolates the execution of the grep, which is really what you're testing at that point.

@sstephenson
Copy link
Owner

You're misunderstanding how bats works. "run" is not special syntax—it is just another command.

run cat /etc/ssh/ssh_known_hosts | grep github pipes the output of run (there is none) to grep.

You don't need the cat at all, or even the run, if you just want to check whether a file has a matching string in it. grep takes a file argument and returns a non-zero exit status when there are no matches.

@test "Test if GitHub is in the global ssh_known_hosts file" {
    grep github /etc/ssh/ssh_known_hosts
}

@dobbs
Copy link

dobbs commented Mar 17, 2014

If you need to test against the output of a pipe, capture it yourself instead of trying to use 'run'.

@test "Test if GitHub is in the global ssh_known_hosts file" {
found=$(cat /etc/ssh/ssh_known_hosts | grep github)
[ "$found" = "..." ]
}

@inthecloud247
Copy link

heya... bats is rad. cool project. Finally figured out a way to get this to work as expected... wrap it in a bash -c command.

@test "linux: running 64-bit kernel" {
  run bash -c "uname -a | grep -o x86_64 | wc -m"
  echo "output: "$output
  echo "status: "$status
  [ "$status" -eq 0 ]
  [ "$output" -ne 0 ]
}

I also have debug messages here that only show if the test fails. works well.

@LvChengbin
Copy link

To use eval might be a better option, such as run eval echo "xx" | cmd, so that you don't need to export variables to subshells.

@carlosonunez
Copy link

run is a command, so the contents from run will be piped into its right-hand side. Use shell redirection like this as a workaround:

@test "Use grep in BATS tests" {
  run grep -q "$item_to_find" <(command_to_run)
  [ "$status" -eq 0 ]
}

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants