Use cabal2nix to create derivation from cabal test target?

I’m trying to create a derivation for the test target of cabal based haskell project. I’m able to use cabal2nix to create a derivation from the executable target. I can’t figure out how to do it for the test target.

Here’s what I have so far in the flake. Also here’s a full minimal example with a simple cabal haskell project included: GitHub - idrisr/cabal2nix-question. You should be able to clone it and have a working example. Thanks in advance!

{
  inputs = {
    nixpkgs.url = "github:nixos/nixpkgs/23.11";
    flake-utils.url = "github:numtide/flake-utils";
  };
  outputs = { nixpkgs, flake-utils, ... }:
    let
      system = flake-utils.lib.system.x86_64-linux;
      compiler = "ghc948";
      pkgs = nixpkgs.legacyPackages.${system};
      my-haskell-exe =
        pkgs.haskell.packages."${compiler}".callCabal2nix "what-goes-here?"
        ./my-haskell-project { };
      # my-haskell-test = how to make a derivation from the cabal test target?;
    in {
      packages.${system} = { default = my-haskell-exe; };
      checks.${system} = { default = my-haskell-exe; };
    };
}

Try setting buildTarget to the name of the test suite(s) you want to install. Not sure if it will work without a hitch though. Alternatively you can override buildPhase/installPhase of course.

Well, I tried reading a bunch of source in cabal2nix and the haskell sections of nixpkgs, and didn’t figure out how to just run the test target of a cabal package. It’s possible that the premise of my question is just wrong—creating a derivation for the test target separate from the library target of the package doesn’t make any sense.

The default value of doCheck used in haskellPackages.mkDerivation is set to true, as documented here, so the test target is already being tested, which I didn’t realize until purposely creating a failing test and observing that the package didn’t build.

What are you trying to achieve exactly? Do you want to build and install the test suites only or do you want to run the test suite only in the derivation?

The default behavior is to build and install all normal targets (executables and non-internal library) as well as build and execute all test suite (but not install the associates executables, of course).

What are you trying to achieve exactly?

I want the build to fail if the test suites fail.

The default behavior is to build and install all normal targets (executables and non-internal library) as well as build and execute all test suite (but not install the associates executables, of course).

Ok, this is now my understanding as well. The default behavior will do what I need.

Thanks.

What if one did want to produce an output that contained one of the test suite executables from the .cabal file?

For example, maybe there’s an integration test suite which can’t be run without additional external dependencies (a database server or something). It seems like it would make sense to build this executable with the cabal2nix tooling and then run it outside of the build environment.

Is anything like that possible?

Cabal doesn’t support installing test targets (this doesn’t really make sense under normal circumstances anyways). I suppose you can theoretically instruct Cabal to build the tests (via --enable-tests), but prevent Nix from running the test suite nor installing normally by providing a no-op checkPhase (don’t disable doCheck since that gates whether the test suite’s deps are available as well!) and creating a custom installPhase that just copies the binaries out of dist via overrideCabal.

Another option is, of course, to invest some time into making it possible to run the integration test suite in Nix. Work done for this tends to help it be more reliable as well usually.