Giter Club home page Giter Club logo

ppx_inline_test's Introduction

ppx_inline_test

Syntax extension for writing in-line tests in ocaml code.

New syntactic constructs

The following constructs are now valid structure items:

let%test "name" = <boolean expr> (* true means ok, false or exn means broken *)
let%test_unit "name" = <unit expr> (* () means ok, exn means broken *)
let%test_module "name" = (module <module-expr>)  (* to group tests (to share
                                                    some setup for instance) *)

We may write _ instead of "name" for anonymous tests. It is also possible to use [%name <string expr>] for a dynamically computed name.

When running tests, they will be executed when the control flow reaches the structure item (i.e. at toplevel for a toplevel test; when the functor is applied for a test defined in the body of a functor, etc.).

Tags

One can tag tests with the following construct:

let%test "name" [@tags "no-js"] = <expr>
let%test "name" [@tags "no-js", "other-tag"] = <expr>
let%test _ [@tags "no-js"] = <expr>
let%test _ [@tags "js-only"] = <expr>

Available tags are:

  • no-js for tests that should not run when compiling Ocaml to Javascript

  • js-only for tests that should only run in Javascript

  • 32-bits-only for tests that should only run in 32 bits architectures

  • 64-bits-only for tests that should only run in 64 bits architectures

  • fast-flambda for tests that might only pass when compiling with flambda or flambda2, -O3, and cross library inlining

  • fast-flambda2 for tests that might only pass when compiling with flambda2, -O3, and cross library inlining

  • x-library-inlining-sensitive for tests that might only pass when compiling with cross library inlining switched on

  • disabled for tests that should not run (unless requested with -require-tag)

One can also tag entire test modules similarly:

let%test_module "name" [@tags "no-js"] = (module struct end)

The flags -drop-tag and -require-tag can be passed to the test runner to restrict which tests are run. We say the tags of a test are the union of the tags applied directly to that test using [@tags ...] and the tags of all enclosing modules. It is to this union that the predicates -drop-tag and -require-tag are applied.

If it is clear, from a test-module's tags, that none of the tests within will possibly match the tag predicates imposed by the command line flags, then additionally the top-level of that module will not be run.

Examples

prime.ml

let is_prime = <magic>

let%test _ = is_prime 5
let%test _ = is_prime 7
let%test _ = not (is_prime 1)
let%test _ = not (is_prime 8)

Tests in a functor.

module Make(C : S) = struct
     <magic>
     let%test _ = <some expression>
end

module M = Make(Int)

Grouping test and side-effecting initialisation.

Since the module passed as an argument to let%test_module is only initialised when we run the tests, it is ok to perform side-effects in the module-expression argument.

let%test_module _ = (module struct
    module UID = Unique_id.Int(struct end)

    let%test _ = UID.create() <> UID.create()
end)

Building and running the tests at jane street

Inline tests can only be used in libraries, not executables.

The standard build rules create an executable script inline_tests_runner which runs all tests in the directory. This script takes optional arguments (see below) to restrict which tests are run.

The full set of tests are run when building the jenga runtest alias.

jenga .runtest

Building and running the tests outside of jane street with dune

Inline tests can only be used in libraries, not executables.

To use this with dune, see dune's documentation. At the time of writing of the current document, the short version is:

  • define a library this way:
(library
  (name foo)
  (inline_tests)
  (preprocess (pps ppx_inline_test)))
  • add tests to it
  • call dune runtest

Building and running the tests outside of jane street without dune

Code using this extension must be compiled and linked using the ppx_inline_test.runtime-lib library. The ppx_inline_test syntax extension will reject any test if it wasn't passed a -inline-test-lib libname flag.

Execution

Tests are only executed when both these conditions are met:

  • the executable containing the tests is linked with ppx_inline_test.runner.lib

  • the executable containing the tests is called with command line arguments:

    your.exe inline-test-runner libname [options]

This libname is a way of restricting the tests run by the executable. The dependencies of your library (or executable) could also use ppx_inline_test, but you don't necessarily want to run their tests too. For instance, core is built by giving -inline-test-lib core and core_extended is built by giving -inline-test-lib core_extended. And now when an executable linked with both core and core_extended is run with a libname of core_extended, only the tests of core_extended are run.

Finally, after running tests, Ppx_inline_test_lib.exit () should be called (to exit with an error and a summary of the number of failed tests if there were errors or exit normally otherwise).

One can construct a dual-use binary that only runs the tests when prompted to (through the command line), by sticking the following piece of code in it, after the tests have run but before the binary starts doing non-test side effects. However be aware that Base.am_testing will be true even when not running tests, which may be undesirable.

match Ppx_inline_test_lib.testing with
| `Testing `Am_test_runner ->
  print_endline "Exiting test suite";
  Ppx_inline_test_lib.exit ()
| `Testing _ -> exit 0
| `Not_testing -> ()

Command line arguments

The executable that runs tests can take additional command line arguments. The most useful of these are:

  • -stop-on-error

    Stop running tests after the first error.

  • -verbose

    to see the tests as they run

  • -only-test location

    where location is either a filename -only-test main.ml, a filename with a line number -only-test main.ml:32, or with the syntax that the compiler uses: File "main.ml", or File "main.ml", line 32 or File "main.ml", line 32, characters 2-6 (characters are ignored). The position that matters is the position of the let%test or let%test_unit.

    The positions shown by -verbose are valid inputs for -only-test.

    If no -only-test flag is given, all the tests are run. Otherwise all the tests matching any of the locations are run.

  • -drop-tag tag

    drop all the tests tagged with tag.

These can be specified to jenga like this:

(library
  (...
   (inline_tests ((flags (-stop-on-error))))
   ...
  ))

and to dune like this:

(library
  ...
  (inline_tests (flags (-stop-on-error)))
  ...)

Parallelizing tests

If you pass arguments of the form -inline-test-lib lib:partition to ppx_inline_test, then you will be able to run tests from a given source file in parallel with tests from other source files. All the tests inside the same source file are still run sequentially.

You should pick different partition names for the different files in your library (the name of the .ml files for instance).

ppx_inline_test_lib currently requires some external system like a build system to run it multiple times in parallel, although we may make it possible to run the inline tests in parallel directly in the future.

If you do that, you can now use two new flags of the executable containing the tests:

  • -list-partitions

    lists all the partitions that contain at least one test, one per line.

  • -partition P

    only run the tests of the library that are encountered at toplevel of the source file that was preprocessed with the given partition P (the tests need not be syntactically in the file, they could be the result of applying a functor)

A build system can combine these two commands by first listing partitions, and then running one command for each partition.

ppx_inline_test's People

Contributors

aalekseyev avatar domq avatar jeremiedimino avatar public-release avatar rootmos avatar sir4ur0n avatar staronj avatar trefis avatar xclerc avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ppx_inline_test's Issues

Embed errors in the AST instead of raising

Currently, when ppx_inline_test encounters an error, it uses the raise_errorf function to raise a located error.

The exception is caught by ppxlib, which in this case:

  • Catch the error,
  • stops the rewriting process
  • add the error (as a [%%%ocaml.error ...] extension node) to the last valid ast
  • Use the resulting AST

The interruption of the rewriting is quite bad for the user experience! The implication for the users are:

  • Since ppx_inline_test runs at the "context-free" phase, the "last valid AST" is before the context-free phase. So, no other derivers/extenders get run, which generates a lot of noise in the errors (such as "uninterpreted extensions" or "unbound identifiers")
  • Only one (meaningful) error from your PPX is reported at a time.
Example

For instance:

let%test ("invalid1" [@tags "invalid"]) = false

let%test ("invalid2" [@tags "invalid"]) = false

let%test ("valid" [@tags "no-js"]) = false

would report several errors:

  • invalid is not a valid tag for inline tests for invalid1: the right error
  • uninterpreted extension test for invalid2: the wrong error, it should be as for invalid1
  • uninterpreted extension test for valid: an error when there should not be one

You can find more information about error reporting in PPXs in this section of the ppxlib manual.

❓ Would you be willing to accept contributions to this issue? I'm considering assigning its resolution as part of an outreachy internship: see more information here.

Warning: overriding the purity of the primitive Base_am_testing: pure -> mutator

When running expect tests/inline tests I get the following warning: Warning: overriding the purity of the primitive Base_am_testing: pure -> mutator. Is this a warning that I need to worry about or address?


Here is an example.

dune

(library
 (name hello)
 (inline_tests
  (modes js))
 (preprocess
  (pps ppx_expect)))

dune-project

(lang dune 3.8)

hello.ml

let%expect_test _ = print_endline "hi" ; [%expect {| hi |}]

Running the tests

$ dune runtest
Warning: overriding the purity of the primitive Base_am_testing: pure -> mutator

Package versions:

  • base v0.15.1
  • dune 3.8.1
  • js_of_ocaml 5.2.0
  • ocaml 4.14.0
  • ppx_expect v0.15.1
  • ppx_inline_test v0.15.1

v0.12.0 is incompatible with let operator syntax

The currently released version is pinned to the previously released version of ppxlib, which seems to be incompatible with the let operator syntax added in OCaml 4.08. As a result, attempts to build projects using the released version of this package result in something like

Fatal error: exception File "lib/lib.ml", line 30, characters 2-6: let operators are not supported before OCaml 4.08

I can see work is underway to put together release v0.13.0, but wanted to note this problem for the record, as it took me some time to debug and figure out the source of the problem.

(Incidentally, I think this is occurring on other Jane Street packages as well, at least including ppx_sexp_conv. I expect this will be a problem for all packages that haven't yet cut new releases to increment to the latest ppxlib.)

Example requires ppx_jane

The example defined in this repo requires ppx_jane which in turn requires ppx_inline_test. This makes the example pretty difficult to build since you need both ppx_jane and ppx_inline_test from findlib or both in your jbuild workspace. It would be nicer if the example only required ppx_inline_test.

Exception-based error reporting is noisy

I'm working on the testing chapter of Real World OCaml, and it highlights that using [%test_eq[ leads to rather noisy error messages, with mostly-nonsense stack traces. Here's the example:

open! Base

let%test_unit "rev" =
  [%test_eq: int list] (List.rev [3;2;1]) [3;2;1]

And here's what the test output looks like.

  $ dune runtest
  File "test.ml", line 3, characters 0-71: rev threw
  (duniverse/ppx_assert.v0.13.0/runtime-lib/runtime.ml.E "comparison failed"
    ((1 2 3) vs (3 2 1) (Loc test.ml:4:13))).
    Raised at file "duniverse/ppx_assert.v0.13.0/runtime-lib/runtime.ml", line 28, characters 28-53
    Called from file "duniverse/ppx_inline_test.v0.13.1/runtime-lib/runtime.ml", line 502, characters 15-19
    Called from file "duniverse/ppx_inline_test.v0.13.1/runtime-lib/runtime.ml", line 343, characters 8-12
    Re-raised at file "duniverse/ppx_inline_test.v0.13.1/runtime-lib/runtime.ml", line 346, characters 6-13
    Called from file "duniverse/ppx_inline_test.v0.13.1/runtime-lib/runtime.ml", line 359, characters 15-52
    Called from file "duniverse/ppx_inline_test.v0.13.1/runtime-lib/runtime.ml", line 446, characters 52-83

  FAILED 1 / 1 tests
  [1]

Is this fixable?

Error: unclosed parentheses at end of input

Distro: Arch Linux
Details: Linux stendarr 4.15.7-1-ARCH #1 SMP PREEMPT Wed Feb 28 19:01:57 UTC 2018 x86_64 GNU/Linux
OCaml compiler: tested with 4.04.1, 4.04.2, 4.06.1

Note that this is happening on a fresh install.

Error log:

=-=- Error report -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
The following actions were aborted
  ∗  install bignum            v0.10.0 
  ∗  install bin_prot          v0.10.0 
  ∗  install core              v0.10.0 
  ∗  install core_kernel       v0.10.0 
  ∗  install ppx_assert        v0.10.0 
  ∗  install ppx_base          v0.10.0 
  ∗  install ppx_bin_prot      v0.10.0 
  ∗  install ppx_custom_printf v0.10.0 
  ∗  install ppx_expect        v0.10.1 
  ∗  install ppx_hash          v0.10.0 
  ∗  install ppx_jane          v0.10.0 
  ∗  install ppx_sexp_message  v0.10.0 
  ∗  install ppx_sexp_value    v0.10.0 
  ∗  install snarky            ~unknown
The following actions failed
  ∗  install ppx_compare     v0.10.0
  ∗  install ppx_fields_conv v0.10.0
  ∗  install ppx_sexp_conv   v0.10.0
  ∗  install ppx_traverse    v0.10.0

In particular, looking further up in the error trace:

[snarky] [email protected]:o1-labs/snarky.git already up-to-date

=-=- Processing actions -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
[ERROR] The compilation of ppx_compare failed at "jbuilder build -p ppx_compare -j 4".
[ERROR] The compilation of ppx_fields_conv failed at "jbuilder build -p ppx_fields_conv -j 4".
[ERROR] The compilation of ppx_sexp_conv failed at "jbuilder build -p ppx_sexp_conv -j 4".
[ERROR] The compilation of ppx_traverse failed at "jbuilder build -p ppx_traverse -j 4".

#=== ERROR while installing ppx_compare.v0.10.0 ===============================#
# opam-version 1.2.2
# os           linux
# command      jbuilder build -p ppx_compare -j 4
# path         /home/erwan/.opam/4.04.2/build/ppx_compare.v0.10.0
# compiler     4.04.2
# exit-code    1
# env-file     /home/erwan/.opam/4.04.2/build/ppx_compare.v0.10.0/ppx_compare-15697-ebe0e0.env
# stdout-file  /home/erwan/.opam/4.04.2/build/ppx_compare.v0.10.0/ppx_compare-15697-ebe0e0.out
# stderr-file  /home/erwan/.opam/4.04.2/build/ppx_compare.v0.10.0/ppx_compare-15697-ebe0e0.err
### stderr ###
# File "/home/erwan/.opam/4.04.2/lib/ppx_inline_test/ppx_inline_test.dune", line 15, characters 0-0:
# Error: unclosed parentheses at end of input

[SIMILAR ERROR LOGS FOR OTHER PACKAGES...]


#=== ERROR while installing ppx_traverse.v0.10.0 ==============================#
# opam-version 1.2.2
# os           linux
# command      jbuilder build -p ppx_traverse -j 4
# path         /home/erwan/.opam/4.04.2/build/ppx_traverse.v0.10.0
# compiler     4.04.2
# exit-code    1
# env-file     /home/erwan/.opam/4.04.2/build/ppx_traverse.v0.10.0/ppx_traverse-15697-899ac0.env
# stdout-file  /home/erwan/.opam/4.04.2/build/ppx_traverse.v0.10.0/ppx_traverse-15697-899ac0.out
# stderr-file  /home/erwan/.opam/4.04.2/build/ppx_traverse.v0.10.0/ppx_traverse-15697-899ac0.err
### stderr ###
# File "/home/erwan/.opam/4.04.2/lib/ppx_inline_test/ppx_inline_test.dune", line 15, characters 0-0:
# Error: unclosed parentheses at end of input

I am a little bit puzzled since the content of $HOME/.opam/4.04.2/lib/ppx_inline_test/ppx_inline_test.dune seems perfectly correct:

(dune
 1
 ((inline_tests.backend
   1.0
   ((runner_libraries (ppx_inline_test.runner.lib))
    (flags
     (inline-test-runner
      ${library-name}
      -source-tree-root
      ${ROOT}
      -diff-cmd
      -))
    (generate_runner ((echo let () = Ppx_inline_test_lib.Runtime.exit ();;)))
    (extends ())))))

non-ghost location in generated code

Hi,

We noticed in aantron/bisect_ppx#387 that ppx_inline_test produces non-ghost located code.
Generated code example:

[@@@ocaml.ppx.context
  {
    tool_name = "ppx_driver";
    include_dirs = [];
    load_path = [];
    open_modules = [];
    for_package = None;
    debug = false;
    use_threads = false;
    use_vmthreads = false;
    recursive_types = false;
    principal = false;
    transparent_modules = false;
    unboxed_types = false;
    unsafe_string = false;
    cookies = [("inline_tests", "enabled"); ("library-name", "trie")]
  }]
let () = Ppx_inline_test_lib.Runtime.set_lib_and_partition "trie" ""
...

Parsetree of the generated code:

...
structure_item (src/trie.ml[4,201+0]..[4,201+0])
    Pstr_value Nonrec
    [
      <def>
        pattern (src/trie.ml[4,201+0]..[4,201+0])
          Ppat_construct "()" (src/trie.ml[4,201+0]..[4,201+0])
          None
        expression (src/trie.ml[4,201+0]..[4,201+0])
          Pexp_apply
          expression (src/trie.ml[4,201+0]..[4,201+0])
            Pexp_ident "Ppx_inline_test_lib.Runtime.set_lib_and_partition" (src/trie.ml[4,201+0]..[4,201+0])
          [
            <arg>
            Nolabel
              expression (src/trie.ml[4,201+0]..[4,201+0])
                Pexp_constant PConst_string("trie",None)
            <arg>
            Nolabel
              expression (src/trie.ml[4,201+0]..[4,201+0])
                Pexp_constant PConst_string("",None)
          ]
    ]
 ...

In our case (for bisect_ppx instrumentation), this creates invalid locations for coverage reports.

(for more context, project can be found here)

Anonymous arguments don't work with merlin

This is a very minor issue, but still worthwhile to report.

If run via ppx_jane -as-ppx anonymous tests yield the following messages:

Extension `test' was not translated.
Hint: `test' is available for structure items but is used here in the context of an expression. Did you put it at the wrong level?

The same is for test_modules.

If run via ppx we just fail with

Uninterpreted extension 'test_module'.

Windows install related bug

Generated ppx_install_test.install misses .exe extension for ppx executable so Windows install is broken. I've fixed this modifying js-utils/install_tags.ml:
replace

let sections =
  [ ("lib",
(*...*)
  ; ("bin",
    [ ("built_exec_ppx", Some "../lib/ppx_inline_test/ppx")

with

let exe fn = if Sys.win32 then fn ^ ".exe" else fn

let sections =
  [ ("lib",
(*...*)
  ; ("bin",
    [ ("built_exec_ppx", Some (exe "../lib/ppx_inline_test/ppx"))

But this problem is common to several modules and probably can be fixed in a more general way.

how to run tests for this package?

I'm trying to figure out how to run the tests for this package, but get an error:

chet@twitter:~/Hack/Camlp5/src/ppx_inline_test$ dune runtest
File "test/dune", line 8, characters 0-897:
 8 | (rule (targets test.output test-partitions.output test-inlining.output)
 9 |  (deps ./inline_tests_runner ./inline_tests_runner.exe)
10 |  (action
....31 |    \n  echo\
32 |    \n  run -require-tag x-library-inlining-sensitive -verbose\
33 |    \n) > test-inlining.output")))
Error: No rule found for test/inline_tests_runner
File "test/dune", line 8, characters 0-897:
 8 | (rule (targets test.output test-partitions.output test-inlining.output)
 9 |  (deps ./inline_tests_runner ./inline_tests_runner.exe)
10 |  (action
....31 |    \n  echo\
32 |    \n  run -require-tag x-library-inlining-sensitive -verbose\
33 |    \n) > test-inlining.output")))
Error: No rule found for test/inline_tests_runner.exe

Any suggestions for how to run these tests?
I forgot to mention that I have the package installed:

 ocamlfind list | grep inline_test
ppx_inline_test     (version: 0.13.1)
ppx_inline_test.config (version: 0.13.1)
ppx_inline_test.drop (version: 0.13.1)
ppx_inline_test.libname (version: 0.13.1)
ppx_inline_test.runner (version: 0.13.1)
ppx_inline_test.runner.lib (version: 0.13.1)
ppx_inline_test.runtime-lib (version: 0.13.1)

Don't require test dependencies when building

Right now it seems like if a PPX test mentions a module, the dependency providing that module must be installed when building the tested code.
This should be made unnecessary, so that only building with runtest requires extra dependencies.

Can't make recent ppx_inline_test work on Windows

I'm trying to make ppx_inline_test.v0.12.0 work on Windows. To enable tests it uses

CAMLprim CAMLweakdef value Base_am_testing()
{
  return Val_false;
}

that is overridden in ppx_inline_test. The problem is that CAMLweakdef is no-op under Windows and the linker always takes base variant (base.cma goes before ppx_inline_test_lib.cma) so tests are always disabled. Any idea how to work around this?

Error using `ppx_inline_test.0.11.0` with `dune>=2.0.0`

Hello,
Using ppx_inline_test version 0.11.0 with dune version 2.3.0 yields the following error message

File "/home/travis/.opam/4.04.1/lib/ppx_inline_test/ppx_inline_test.dune", line 1, characters 0-0:
Warning: .dune files are ignored since 2.0. Reinstall the library with dune
>= 2.0 to get rid of this warning and enable support for the subsystem this
library provides.
File "src/pure/dune", line 4, characters 1-15:
4 |  (inline_tests)
     ^^^^^^^^^^^^^^
Error: No inline tests backend found.

while using with dune version 1.11.4 works.

Update Changelog

The latest ppx_inline_test removes the Ppx_inline_test_lib.Runtime.Test_result.record function and it would be great if this was documented in the changelog. Preferably with a few words on how to migrate.

Be more relaxed about ppx attributes.

In Reason, we preserve the original string content in the AST and attach them to parsed strings (which are manipulated to some extent by the parsing process).

When you write:

let%test "literal" = ..

You effectively end up with:

let%test ("literal" [@@reason.literal_value "literal"]) = ...

And the ppx_inline_test ppx reports: "Error: Attributes not allowed here"

If we'd like to use ppx_inline_test with Reason, then we will need ppx_inline_test to be a little more relaxed about allowing attributes on the string literal. Is this possible?

reasonml/reason#2134

Problems Integrating With Oasis

Switched over from pa_unit camlp4 extension, and changed the syntax of TEST -> let%test. Trying to compile I get:

ppx_inline_test: extension is disabled because the tests would be ignored (the build system didn't pass -inline-test-lib)

I'm using Oasis and it's far from clear to me where to pass this argument, and what to use as a parameter (if any).

Cannot link on Windows (mingw) because of time_now

Version 0.14.0 is using time_now.

It cannot link on Windows when running inline tests (tried with dune)

image

Error returned is the following:

(cd _build/default && C:\OCaml64\home\jthuong\.opam\4.10.0+mingw64c\bin\ocamlopt.opt.exe -w -24 -g -o test/.test_inline.inline-tests/run.exe -linkall C:\\OCaml64\\home\\jthuong\\.opam\\4.10.0+mingw64c\lib\stdlib-shims\stdlib_shims.cmxa C:\\OCaml64\\home\\jthuong\\.opam\\4.10.0+mingw64c\lib\fmt\fmt.cmxa C:\\OCaml64\\home\\jthuong\\.opam\\4.10.0+mingw64c\lib\astring\astring.cmxa C:\\OCaml64\\home\\jthuong\\.opam\\4.10.0+mingw64c\lib\cmdliner\cmdliner.cmxa C:\\OCaml64\\home\\jthuong\\.opam\\4.10.0+mingw64c\lib\fmt\fmt_cli.cmxa C:/OCaml64/home/jthuong/.opam/4.10.0+mingw64c/lib/ocaml\unix.cmxa -I C:/OCaml64/home/jthuong/.opam/4.10.0+mingw64c/lib/ocaml C:\\OCaml64\\home\\jthuong\\.opam\\4.10.0+mingw64c\lib\fmt\fmt_tty.cmxa C:\\OCaml64\\home\\jthuong\\.opam\\4.10.0+mingw64c\lib\uuidm\uuidm.cmxa C:\\OCaml64\\home\\jthuong\\.opam\\4.10.0+mingw64c\lib\re\re.cmxa C:\\OCaml64\\home\\jthuong\\.opam\\4.10.0+mingw64c\lib\alcotest\alcotest.cmxa C:\\OCaml64\\home\\jthuong\\.opam\\4.10.0+mingw64c\lib\base\base_internalhash_types/base_internalhash_types.cmxa -I C:\\OCaml64\\home\\jthuong\\.opam\\4.10.0+mingw64c\lib\base\base_internalhash_types C:\\OCaml64\\home\\jthuong\\.opam\\4.10.0+mingw64c\lib\base\caml/caml.cmxa C:\\OCaml64\\home\\jthuong\\.opam\\4.10.0+mingw64c\lib\sexplib0\sexplib0.cmxa C:\\OCaml64\\home\\jthuong\\.opam\\4.10.0+mingw64c\lib\base\shadow_stdlib/shadow_stdlib.cmxa C:\\OCaml64\\home\\jthuong\\.opam\\4.10.0+mingw64c\lib\base\base.cmxa -I C:\\OCaml64\\home\\jthuong\\.opam\\4.10.0+mingw64c\lib\base C:\\OCaml64\\home\\jthuong\\.opam\\4.10.0+mingw64c\lib\ppx_inline_test\config/inline_test_config.cmxa C:\\OCaml64\\home\\jthuong\\.opam\\4.10.0+mingw64c\lib\jane-street-headers\jane_street_headers.cmxa C:\\OCaml64\\home\\jthuong\\.opam\\4.10.0+mingw64c\lib\ppx_sexp_conv\runtime-lib/ppx_sexp_conv_lib.cmxa C:\\OCaml64\\home\\jthuong\\.opam\\4.10.0+mingw64c\lib\ppx_compare\runtime-lib/ppx_compare_lib.cmxa C:\\OCaml64\\home\\jthuong\\.opam\\4.10.0+mingw64c\lib\ppx_enumerate\runtime-lib/ppx_enumerate_lib.cmxa C:\\OCaml64\\home\\jthuong\\.opam\\4.10.0+mingw64c\lib\ppx_hash\runtime-lib/ppx_hash_lib.cmxa C:\\OCaml64\\home\\jthuong\\.opam\\4.10.0+mingw64c\lib\time_now\time_now.cmxa -I C:\\OCaml64\\home\\jthuong\\.opam\\4.10.0+mingw64c\lib\time_now C:\\OCaml64\\home\\jthuong\\.opam\\4.10.0+mingw64c\lib\ppx_inline_test\runtime-lib/ppx_inline_test_lib.cmxa test/test_inline.cmxa C:\\OCaml64\\home\\jthuong\\.opam\\4.10.0+mingw64c\lib\ppx_inline_test\runner/lib/ppx_inline_test_runner_lib.cmxa -I C:\\OCaml64\\home\\jthuong\\.opam\\4.10.0+mingw64c\lib\ppx_inline_test\runner/lib test/.test_inline.inline-tests/.test_inline.inline-tests.eobjs/native/dune__exe__Run.cmx)
** Cannot resolve symbols for C:\\OCaml64\\home\\jthuong\\.opam\\4.10.0+mingw64c\lib\time_now\libtime_now_stubs.a(time_now_stubs.o/
):
 clock_gettime
File "caml_startup", line 1:
Error: Error during linking

I am using

  • dune version 2.5.1
  • time_now version 0.14.0
  • compiler ocaml-variants.4.10.0+mingw64c

My mini project is the following:
dune_test.zip

Thank you @jeremiedimino for pointing me in the right direction.

Debugging 0 tests

Is there a way to debug test discovery? I have a separate executable for running tests, but once I run it, no tests are actually executed.

The repository is available here. To reproduce the issue do:

$ make test
# ...
0 tests ran, 0 test_modules ran

Add instructions for using with jbuilder

Currently the documentation only describes how to use this library with jenga or ocamlbuild. Since jbuilder seems to be gaining steam as a popular build system for the OCaml ecosystem, it would be great to have some guidance on how to build inline tests with it.

Configuration to stop at first failure

Sometimes it's useful to stop at test run at the first failure, instead of getting a list of all error.

  1. When all tests break because of a small change, the first failure might be the most interesting one
  2. In a CI, you might not want to waste CPU resources after the first failure, especially when the test suit takes many minutes to complete fully

Compare with PHPUnit --stop-on-failure.

Cannot run tests in bytecode mode

When I run inline tests in bytecode mode, I get the following message:

You are doing something unexpected with the tests. No tests have
been run. You should use the inline_tests_runner script to run
tests.

It seems that Base.Exported_for_specific_uses.am_testing is false when compiling to bytecode. Removing the check fixes the issue:

when Base.Exported_for_specific_uses.am_testing -> begin

This is with Base v0.13.0.

Js-of-ocaml code fails with "Base_am_testing not implemented"

image

It seems that there is: a runtime.js there: https://github.com/janestreet/ppx_inline_test/blob/44c2aac3a7657875ee957cd6877522f474acbca1/runner/lib/runtime.js

I don't use ppx_inline_test nor Base but I guess some dependency (most likely ppx_sexp_conv) is tracking one of them into my JSOO output?

How do I get that runtime.js?

I guess I need to set exact opam constraints for older released versions of my Web UI, when did this "global module inititialization" code appear?

Name suffix for test modules

With ppx_bench's inline benchmark modules, you can set a name suffix (example).

It seems there's no way to do something similar with this package. Would it be possible to add that feature?

running a single test

Hey!

I'm trying to run a single test via:

../../../../../_build/default/src/lib/pickles/.pickles.inline-tests/inline_test_runner_pickles.exe inline-test-runner Pickles -only-test pickles.ml:981

but I'm getting

ppx_inline_test error: the following -only-test flags matched nothing: pickles.ml:981.

whereas the file indeed exists at my path. I'm a bit confused on how to use that option

Pre/post hook for each test

I'ts preferred to have this capability, for example, to manage resources such as DB connection, without boilerplating.

Doesn't work with Merlin

at least out of box :)

Merlin reports a code, that uses this extension as an error:

ppx_inline_test: extension is disabled because the tests would be ignored (the build system didn't pass -inline-test-lib) 

I suspect, that the same result would be for other inliners, i.e., ppx_expect and ppx_benchmark.

Currently we have two ways to pass ppx options to ocamlmerlin:

  1. via FLG -ppx but this option is kind of broken, as we can pass only one word after the ppx, everything else, is considered as ocamlmerlin option (I will report this to upstream)
  2. via PKG name, where package name has a META file with ppx and ppxopt fields.

It looks like the latter is default and expected way to use ppx in merlin (and hence better supported). So a good solution for this issue would be to add dummy package ppx_inliner.libname.for_merlin that will automatically disable libname checking (or add "dummy" libname). It would be also a good idea for the merlin to pass "merlin" predicate, when it performs lookup, so that this dummy library, can be chosen automatically.

Temporal workaround

Maybe this information would be useful, for those who come after me. As a temporal workaround, I put in the search path a file ppx-bap with the following contents:

ppx-jane -as-ppx -inline-test-lib bap $@

And then I put option:

FLG -ppx ppx-bap

into my .merlin file.

Don't show test output unless tests fail

Our code does a lot of logging, which makes it really hard to quickly tell which test failed when looking at our test output. Is there a way ppx_inline_test could hide stdout unless a test fails?

I looked into implementing this myself with Runtime.am_running_inline_test, but I would also need a way to know when a test starts and stops, and also know whether it passed or failed.

(One option is to get rid of all output when tests are running, but then it's really difficult to debug failing tests)

I could also implement my own test runner, but it's not clear to me what I would need to do there since the built-in runner just calls Ppx_inline_test_lib.Runtime.exit ().

TAP output support

I'd really love a command-line flag to the test-runner, analogous to -verbose, that allows me to generate TAP-output from running tests instead of a custom format. This would allow:

  1. Integration of multiple external testing systems upon make test (JavaScript-side tests using Mocha or similar, command-line integration tests using BATS, etceteras.)

  2. Integration of multiple internal testing systems' output (should I open an identical Issue on ppx_expect?)

  3. Integration with any higher-level TAP consumers

  4. Beautification of test-output without the writing and maintenance of a ton of colourization and such code in this library itself (TAP is designed to be piped into some really cool reporters, y'dig?)

    clip

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.