haskell / haskell/cabal

Access the executable build by `cabal build` (with a custom `Setup.hs`) from `cabal test`

Open
#7,577 11 comments 0 reactions 0 assignees View on GitHub
attention: pr-welcome build-type: custom Cabal: cmd/test type: bug
Dominant language
Haskell
Stars
1.7k
Forks
750
Avg merge
4d 3h
Merged PRs (30d)
28

Description

Question: What is the canonical way to write a `test-suite` that calls the `executable` as process, e.g. via `system`?

While writing up the question, I discovered an __answer__ that I want to share here, since I could not discover it so far by googling (despite many tries). This answer could possibly find its way into the documentation, e.g. near https://cabal.readthedocs.io/en/3.4/cabal-package.html#example-package-using-exitcode-stdio-1-0-interface.

Here is a minimal test-suite code `Test.hs` that tries to call the executable `hello-world` defined in the same cabal project:
```haskell
import System.Exit ( exitWith )
import System.Process ( system )

main :: IO ()
main = exitWith =<< system ("hello-world")
```
We can run `hello-world` via `cabal run -- hello-world`.
However, without special provision, `cabal test` fails:
```
Build profile: -w ghc-9.0.1 -O1
In order, the following will be built (use -v for more details):
- hello-1.0.0.3 (test:hello-test)
...
Running 1 test suites...
Test suite hello-test: RUNNING...
/bin/sh: hello-world: command not found

Test suite hello-test: FAIL
```

The __solution__ is to add the executable to the `test-suite` stanza, via field `build-tool-depends`:
```cabal
name: hello-world
version: 0.0.1
cabal-version: >= 1.8
build-type: Simple

executable hello-world
hs-source-dirs: .
main-is: Main.hs
build-depends: base >= 4.2 && < 5

test-suite hello-test
type: exitcode-stdio-1.0
hs-source-dirs: .
main-is: Test.hs
build-depends: base, process
build-tool-depends: hello-world:hello-world
```

For completeness, here is `Main.hs`:
```haskell
main = putStrLn "Hello, World!"
```

Now `cabal test` works!
```
Build profile: -w ghc-9.0.1 -O1
In order, the following will be built (use -v for more details):
- hello-world-0.0.1 (exe:hello-world) (first run)
- hello-world-0.0.1 (test:hello-test) (first run)
...
Building executable 'hello-world' for hello-world-0.0.1..
...
Building test suite 'hello-test' for hello-world-0.0.1..
...
Running 1 test suites...
Test suite hello-test: RUNNING...
Test suite hello-test: PASS
```

Context: https://github.com/agda/agda/issues/5302#issuecomment-903771697

Please tag this issue with `cabal-install: cmd/test` and `type: user question`.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.