How to unit test the command line interface

I wrote a command line tool that I want to test (I don't want to run unit tests from the command line). I want to map a specific set of input parameters to a specific output. I could not find any existing tools for this. The application is just binary and can be written in any language, but it takes POSIX parameters and writes to standard output.

Something line by line:

  • For each known set of input parameters:
    • Launch the application with the specified input.
    • Outputting the pipe to a file.
    • Output the output to the output (saved) (desired).
    • If diff is not empty, please note the error.

(Btw, is this what you call an integration test, not a unit test?)

Edit: I know how I'm going to write my own tool for this, I don't need any help with the code. I want to know if this has already been done.

+3


source to share


4 answers


DejaGnu is a mature and somewhat standard framework for writing test suites for CLI programs.

Here's an example test taken from this tutorial :



# send a string to the running program being tested:
send "echo Hello world!\n"

# inspect the output and determine whether the test passes or fails:
expect {
    -re "Hello world.*$prompt $" {
        pass "Echo test"
    }
    -re "$prompt $" {
        fail "Echo test"
    }
    timeout {
        fail "(timeout) Echo test"
    }
}

      

Using a well-established structure like this is likely to be better in the long run than anything you can think of yourself if your needs aren't very simple.

+5


source


You're looking for BATS (Bash Automated Testing System): https://github.com/bats-core/bats-core

From the docs:



example.bats contains
#!/usr/bin/env bats

@test "addition using bc" {
  result="$(echo 2+2 | bc)"
  [ "$result" -eq 4 ]
}  

@test "addition using dc" {
  result="$(echo 2 2+p | dc)"
  [ "$result" -eq 4 ]
}


$ bats example.bats

 ✓ addition using bc
 ✓ addition using dc

2 tests, 0 failures

      

+3


source


Well, I think every language should have a way to execute an external process.

In C #, you can do something like:

var p = new Process();
p.StartInfo = new ProcessStartInfo(@"C:\file-to-execute.exe");
... //You can set parameters here, etc.
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardInput = true;
p.StartInfo.UseShellExecute = false;
p.Start();

//To read the standard output:
var output = p.StandardOutput.ReadToEnd();

      

I've never had to write to standard input, but I believe it can be done by accessing p.StandardInput

. The idea is to treat both entrances as objects Stream

, because that is what they are.

Python has a module subprocess

. According to its documentation:

The subprocess module allows you to create new processes, connect to their I / O / error pipes, and get their return codes.

I had to do the same when I write unit tests for the code generation part of the compiler that I am writing a few months ago: Writing unit tests in my compiler (which generates the IL)

0


source


Of course, this has been done literally thousands of times. But writing a tool to run simple shell scripts or batch files like what you suggest is a trivial task, hardly worth trying to become a generic tool.

-2


source







All Articles