Coder Social home page Coder Social logo

eftest's Introduction

Eftest

Build Status

Eftest is a fast and pretty Clojure test runner.

Installation

To install, add the following to your project :dependencies:

[eftest "0.6.0"]

Alternatively, if you just want to use Eftest as a lein test replacement, add the following to your project :plugins:

[lein-eftest "0.6.0"]

Screenshots

When all the tests pass, it looks like this:

Passing example

When a test fails, it looks like:

Failing example

And when a test throws an exception, it looks like:

Erroring example

Usage

Library

Eftest has two main functions: find-tests and run-tests.

The find-tests function searches a source, which can be a namespace, directory path, symbol, var, or a collection of any of the previous. It returns a collection of test vars found in the source.

The run-tests function accepts a collection of test vars and runs them, delivering a report on the tests as it goes.

Typically these two functions are used together:

user=> (require '[eftest.runner :refer [find-tests run-tests]])
nil
user=> (run-tests (find-tests "test"))
...

The above example will run all tests found in the "test" directory.

Multithreading

By default Eftest runs all tests in parallel, which can cause issues with tests that expect to be single-threaded. To disable this and set all tests to be executed in serial, set the :multithread? option to false:

user=> (run-tests (find-tests "test") {:multithread? false})

If you want the test vars inside a namespace to be executed in parallel, but the namespaces themselves to be executed in serial, then set the :multithread? option to :vars:

user=> (run-tests (find-tests "test") {:multithread? :vars})

If you want the vars inside a namespace to execute in serial, but the namespaces to be executed in parallel, set the :multithread? option to :namespaces:

user=> (run-tests (find-tests "test") {:multithread? :namespaces})

Alternatively, you can add the :eftest/synchronized key as metadata to any tests you want to force to be executed in serial:

(deftest ^:eftest/synchronized a-test
  (is (= 1 1)))

Or you can synchronize the entire namespace:

(ns ^:eftest/synchronized foo.core-test
  (:require [clojure.test :refer :all]
            [foo.core :refer :all]))
Setting the number of threads used

When multithreading is enabled, Eftest uses a single fixed-threadpool ExecutorService to run all selected tests.

By default, Eftest will instantiate the threadpool with the number of processors (cores) available to the JVM, as reported by Runtime.availableProcessors. (NB: in some circumstances, such as in a CircleCI test container, Runtime.availableProcessors returns an erroneous value.)

Users can override the default behavior by including the key :thread-count in the options map supplied to run-tests with the value being any positive integer:

user=> (run-tests (find-tests "test") {:thread-count 4})

Reporting

You can also change the reporting function used. For example, if you want a colorized reporter but without the progress bar:

user=> (run-tests (find-tests "test") {:report eftest.report.pretty/report})

Or JUnit output:

user=> (run-tests (find-tests "test") {:report eftest.report.junit/report})

Or maybe you just want the old Clojure test reporter:

user=> (run-tests (find-tests "test") {:report clojure.test/report})

If you want to redirect reporting output to a file, use the eftest.report/report-to-file function:

user=> (require '[eftest.report :refer [report-to-file]])
nil
user=> (require '[eftest.report.junit :as ju])
nil
user=> (run-tests (find-tests "test") {:report (report-to-file ju/report "test.xml")})

Output capturing

By default the STDOUT and STDERR from each test is captured, and displayed only if the test fails. This includes all the output generated by the test itself, and any output generated by other threads not currently running a test.

To turn off this behavior, set the :capture-output? option to false:

user=> (run-tests (find-tests "test") {:capture-output? false})

Fast failure

Sometimes it's useful to end the testing on the first test failure. To do this set the :fail-fast? option to true:

user=> (run-tests (find-tests "test") {:fail-fast? true})

Long test reporting

If you wish to monitor the length of time to run each test, you can set the :test-warn-time option to the threshold in milliseconds you wish to warn on long test for. The measured duration includes the running of :each-fixtures, but not :once-fixtures.

If you know a particular test to be slow and are ok with that, and don't want to continually be warned about it, you can add the metadata :eftest/slow to either the individual test, or the entire namespace, to prevent reporting.

Note that currently only the pretty and progress reporters support logging long tests.

;; Warns for all tests that take longer than 500ms
user=> (run-tests (find-tests "test") {:test-warn-time 500})

Plugin

To use the Lein-Eftest plugin, just run:

lein eftest

You can customize the reporter and configure the concurrency settings by adding an :eftest key to your project map:

:eftest {:multithread? :vars
         :thread-count 4
         :report eftest.report.junit/report
         ;; You can optionally write the output to a file like so:
         :report-to-file "target/junit.xml"}

Leiningen test selectors also work. With namespaces:

lein eftest foo.bar-test foo.baz-test

And with metadata keywords:

lein eftest :integration

License

Copyright © 2019 James Reeves

Distributed under the Eclipse Public License either version 1.0 or (at your option) any later version.

eftest's People

Contributors

ascho avatar ayato-p avatar danielcompton avatar daveyarwood avatar deraen avatar dm3 avatar eraserhd avatar facundoolano avatar frenchy64 avatar gsnewmark avatar jarppe avatar jcf avatar jeiwan avatar kawas44 avatar miikka avatar nachomdo avatar ryfow avatar sgerrand avatar tanzoniteblack avatar tonsky avatar weavejester avatar ztellman 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  avatar  avatar  avatar

eftest's Issues

Exit codes overflow

Since lein eftest copies a lot of code from leiningen.test, I think it might suffer from exit codes overflowing that was recently fixed in leiningen.test.

This line probably should be wrapped in a (min 1 ...) to limit to small exit codes.

Not reloading file when repeatedly finding tests

Currently, require-namespaces-in-dir doesn't reload the vars in a given namespace or directory of namespaces. This is an issue when running tests from a REPL and find-tests doesn't see new or modified tests.

This line is the issue. If (require ns) were to be instead, (require (into [] (concat ns [:reload :all]))), it would (probably) fix the issue and find new and updated tests.

Unless I've missed something, in which case, anyone care to tell me how to do this?

NPE in test

I am getting this:

                                                                              ERROR in  (Numbers.java:1095)
expected: (< avg-mae max-avg-loss)
  actual: 
java.lang.NullPointerException: Cannot invoke "Object.getClass()" because "x" is null
                                             ...                         
                          progrock.core/bar-text           core.clj:   33
                            progrock.core/render           core.clj:   91
                             progrock.core/print           core.clj:  104
           eftest.report.progress/print-progress       progress.clj:   18
              eftest.report.progress/eval2715/fn       progress.clj:   42
                                             ...                         
                          clojure.test/do-report           test.clj:  357

Using an other test runner, all tests apss

Slow test names incorrect

This is a regression somewhere between 0.5.0 and 0.5.2.

Under 0.5.2, but not 0.5.0, the names of slow tests have begun referring to fixtures instead of the actual test var.

Before (0.5.0):

LONG TEST in org.kidblog.rollouts.test-rollout/test-generated-rollouts
Test took 7.267 seconds seconds to run

Now (0.5.2):

LONG TEST in org.kidblog.rollouts.test-rollout during :clojure.test/once-fixtures
Test took 5.051 seconds seconds to run

Clojure CLI tool support

Hi,

With Clojure 1.9.0 we can use CLI tool for small project and create alias to launch the main function of any program.

We could enhance the project with a -main entry point to allow usage from CLI tool.

Regards

Indenting is wrong for multi-line failure results

If eftest's expected/actual output spans multiple lines then the extra lines aren't indented enough. They need to have the additional indentation provided by expected: prefixed before they are printed.

$ lein eftest

FAIL in eftest-test.core-test/my-test (core_test.clj:10)
expected: {:a 1,
 :aaaaaaaaa 12512521,
 :b "abdksdaflsdfjsdkfla",
 :bbbbbbbb 1251251212512512,
 :ccccccccc ""}
  actual: {:a 2, :b "abdksdfksdflaksdfal"}

FAIL in eftest-test.core-test/a-test (core_test.clj:7)
FIXME, I fail.
expected: 0
  actual: 1

2/2   100% [==================================================]  ETA: 00:00

Ran 2 tests in 0.035 seconds
2 assertions, 2 failures, 0 errors.
Tests failed.

I think humane-test-output does this using pp/pprint-logical-block to add the prefixes.

Is printing serialized?

I'm trying eftest using all of my 16 cores and am seeing this partially garbled output:

Testing
Testing gpml.db.updater-test

Testing
Testing
Testing  gpml.handler.auth-test

Testing gpml.handler.activity-test
gpml.handler.technology-test
Testinggpml.handler.favorite-test

Testing gpml.handler.policy-test

Testing
 gpml.db.landing-test

Testing gpml.handler.util-test
gpml.db.activity-testgpml.handler.resource.translation-test

Thanks - V

Spec validation failures break the runner

Hello folks/weavejester 😄

It seems that spec validations break. I am using eftest.runner from within boot and I see the following when spec does not validate:

Uncaught exception, not in assertion.
expected: nil
  actual: 
clojure.lang.Compiler$CompilerException: java.lang.ClassCastException: eftest.runner$synchronize$fn__2894 cannot be cast to clojure.lang.MultiFn, compiling:(clojure/test/check/clojure_test.cljc:95:1)
           java.lang.ClassCastException: eftest.runner$synchronize$fn__2894 cannot be cast to clojure.lang.MultiFn
                                    clojure.core/get-method                     core.clj: 1809
                  clojure.test.check.clojure-test/eval10462            clojure_test.cljc:   95
                                                        ...                                   
                                       clojure.core/load/fn                     core.clj: 6046
                                          clojure.core/load                     core.clj: 6045
                                          clojure.core/load                     core.clj: 6029
                                                        ...                                   
                                      clojure.core/load-one                     core.clj: 5848
                                   clojure.core/load-lib/fn                     core.clj: 5888
                                      clojure.core/load-lib                     core.clj: 5887
                                      clojure.core/load-lib                     core.clj: 5868
                                                        ...                                   
                                         clojure.core/apply                     core.clj:  659
                                     clojure.core/load-libs                     core.clj: 5925
                                     clojure.core/load-libs                     core.clj: 5909
                                                        ...                                   
                                         clojure.core/apply                     core.clj:  659
                                       clojure.core/require                     core.clj: 5947 (repeats 2 times)
                                                        ...                                   
               clojure.test.check/eval10425/loading--auto--                   check.cljc:   10
                               clojure.test.check/eval10425                   check.cljc:   10
                                                        ...                                   
                                       clojure.core/load/fn                     core.clj: 6046
                                          clojure.core/load                     core.clj: 6045
                                          clojure.core/load                     core.clj: 6029
                                                        ...                                   
                                      clojure.core/load-one                     core.clj: 5848
                                   clojure.core/load-lib/fn                     core.clj: 5888
                                      clojure.core/load-lib                     core.clj: 5887
                                      clojure.core/load-lib                     core.clj: 5868
                                                        ...                                   
                                         clojure.core/apply                     core.clj:  659
                                     clojure.core/load-libs                     core.clj: 5925
                                     clojure.core/load-libs                     core.clj: 5909
                                                        ...                                   
                                         clojure.core/apply                     core.clj:  659
                                       clojure.core/require                     core.clj: 5947 (repeats 2 times)
                                                        ...                                   
                         clojure.spec.gen.alpha/dynaload/fn                    alpha.clj:   22
                            clojure.spec.gen.alpha/dynaload                    alpha.clj:   21
                                  clojure.spec.gen.alpha/fn                    alpha.clj:   29
                                                        ...                                   
                                         clojure.core/deref                     core.clj: 2312
                         clojure.spec.gen.alpha/quick-check                    alpha.clj:   32
                         clojure.spec.gen.alpha/quick-check                    alpha.clj:   30
                                                        ...                                   
                             clojure.spec.alpha/validate-fn                    alpha.clj: 1738
               clojure.spec.alpha/fspec-impl/reify/conform*                    alpha.clj: 1759
                                 clojure.spec.alpha/conform                    alpha.clj:  164
                                      clojure.spec.alpha/dt                    alpha.clj:  760
                                      clojure.spec.alpha/dt                    alpha.clj:  756
                                   clojure.spec.alpha/deriv                    alpha.clj: 1530
                                   clojure.spec.alpha/deriv                    alpha.clj: 1538
                              clojure.spec.alpha/re-conform                    alpha.clj: 1665
          clojure.spec.alpha/regex-spec-impl/reify/conform*                    alpha.clj: 1706
                                 clojure.spec.alpha/conform                    alpha.clj:  164
          clojure.spec.test.alpha/spec-checking-fn/conform!                    alpha.clj:  121
                clojure.spec.test.alpha/spec-checking-fn/fn                    alpha.clj:  140
                                                        ...                                   
                       rest-resources-viz.extractor-test/fn           extractor_test.clj:   36
                                   clojure.test/test-var/fn                     test.clj:  716
                                      clojure.test/test-var                     test.clj:  716
                              eftest.runner/test-vars/fn/fn                   runner.clj:   66
                               clojure.test/default-fixture                     test.clj:  686
                                 eftest.runner/test-vars/fn                   runner.clj:   62
                      eftest.runner/wrap-test-with-timer/fn                   runner.clj:   30
                                 eftest.runner/test-vars/fn                   runner.clj:   76
               rest-resources-viz.extractor-test/wrap-setup           extractor_test.clj:   20
                        clojure.test/compose-fixtures/fn/fn                     test.clj:  693
                               clojure.test/default-fixture                     test.clj:  686
                           clojure.test/compose-fixtures/fn                     test.clj:  693
                                    eftest.runner/test-vars                   runner.clj:   70
                                eftest.runner/test-ns/fn/fn                   runner.clj:   83
                                clojure.core/with-redefs-fn                     core.clj: 7434
                                   eftest.runner/test-ns/fn                   runner.clj:   83
                                      eftest.runner/test-ns                   runner.clj:   83
                                  eftest.runner/test-all/fn                   runner.clj:   90
                                        clojure.core/map/fn                     core.clj: 2747
                                                        ...                                   
                                         clojure.core/apply                     core.clj:  659
                                     eftest.runner/test-all                   runner.clj:   91
                                    eftest.runner/run-tests                   runner.clj:  148
                   metosin.bat-test.impl/reload-and-test/fn                     impl.clj:  161
                  metosin.bat-test.impl/maybe-run-cloverage                     impl.clj:  125
                      metosin.bat-test.impl/reload-and-test                     impl.clj:  159
                                  metosin.bat-test.impl/run                     impl.clj:  200
                                                        ...                                   
                                         clojure.core/apply                     core.clj:  657
                                      boot.pod/eval-fn-call                      pod.clj:  359
                                          boot.pod/call-in*                      pod.clj:  410
                                                        ...                                   
org.projectodd.shimdandy.impl.ClojureRuntimeShimImpl.invoke  ClojureRuntimeShimImpl.java:  109
org.projectodd.shimdandy.impl.ClojureRuntimeShimImpl.invoke  ClojureRuntimeShimImpl.java:  102
                                                        ...                                   
                                          boot.pod/call-in*                      pod.clj:  413
                         metosin.bat-test/eval1541/fn/fn/fn                 bat_test.clj:   52
                       boot.task.built-in/fn/fn/fn/fn/fn/fn                 built_in.clj:  442
                          boot.task.built-in/fn/fn/fn/fn/fn                 built_in.clj:  442
                             boot.task.built-in/fn/fn/fn/fn                 built_in.clj:  439
                                        boot.core/run-tasks                     core.clj: 1021
                                          boot.core/boot/fn                     core.clj: 1031
                        clojure.core/binding-conveyor-fn/fn                     core.clj: 2022
                                                        ...                                   
                        java.util.concurrent.FutureTask.run              FutureTask.java:  266
          java.util.concurrent.ThreadPoolExecutor.runWorker      ThreadPoolExecutor.java: 1149
         java.util.concurrent.ThreadPoolExecutor$Worker.run      ThreadPoolExecutor.java:  624
                                       java.lang.Thread.run                  Thread.java:  748


2/2   100% [==================================================]  ETA: 00:00

All good in vanilla boot.test where I can see the failure properly. Of course eftest feels like a faster/better testing tool so I will try to investigate more.

lein eftest doesn't seem to run my clean up function

In my tests as part of this project, I create a directory (events-directory) and then some directories inside it. At the beginning of each test, I have a clean up function, there-are-no-events that just deletes anything inside events-directory.

Curiously, when I run lein eftest, one of the tests, the-events-page-lists-events-by-date-descending, is failing because it finds more data there than there should be. This suggests that the clean up function isn't being run for some reason. If, however, I run lein test, everything is as expected and the clean up happens.

What am I missing here?

NPE whenever I use a non-default reporter

If I uncomment the option map at https://github.com/lacuna/bifurcan/blob/master/test/bifurcan/run_tests.clj#L12, I'll get the following error. Having looked over the code, I don't see any obvious reason for this to be the case, though maybe it's some sort of loading race condition?

Caused by: java.lang.NullPointerException
	at java.util.concurrent.ConcurrentHashMap.get(ConcurrentHashMap.java:936)
	at clojure.lang.Namespace.find(Namespace.java:188)
	at clojure.core$find_ns.invokeStatic(core.clj:4000)
	at clojure.core$the_ns.invokeStatic(core.clj:4030)
	at clojure.core$the_ns.invoke(core.clj:4023)
	at eftest.runner$test_ns.invokeStatic(runner.clj:31)
	at eftest.runner$test_ns.invoke(runner.clj:30)
	at eftest.runner$test_all$fn__5800.invoke(runner.clj:40)
	at clojure.core$map$fn__4785.invoke(core.clj:2646)
	at clojure.lang.LazySeq.sval(LazySeq.java:40)
	at clojure.lang.LazySeq.seq(LazySeq.java:49)
	at clojure.lang.Cons.next(Cons.java:39)
	at clojure.lang.RT.boundedLength(RT.java:1749)
	at clojure.lang.RestFn.applyTo(RestFn.java:130)
	at clojure.core$apply.invokeStatic(core.clj:648)
	at clojure.core$apply.invoke(core.clj:641)
	at eftest.runner$test_all.invokeStatic(runner.clj:41)
	at eftest.runner$test_all.invoke(runner.clj:38)
	at eftest.runner$run_tests.invokeStatic(runner.clj:93)
	at eftest.runner$run_tests.invoke(runner.clj:76)
	at bifurcan.run_tests$_main.invokeStatic(run_tests.clj:9)
	at bifurcan.run_tests$_main.doInvoke(run_tests.clj:5)
	at clojure.lang.RestFn.invoke(RestFn.java:397)
	at clojure.lang.Var.invoke(Var.java:375)
	at user$eval5846.invokeStatic(form-init8518620352353107416.clj:1)
	at user$eval5846.invoke(form-init8518620352353107416.clj:1)
	at clojure.lang.Compiler.eval(Compiler.java:6927)
	at clojure.lang.Compiler.eval(Compiler.java:6917)
	at clojure.lang.Compiler.load(Compiler.java:7379)

JUnit formatter doesn't play nice with test.check

Hey James,

Because both the JUnit formatter and test.check print to test out you end up with hash maps in the XML output.

[snip]
</testcase>{:result true, :num-tests 100, :seed 1500392295920, :test-var "t-params->map-keys"}
<testcase name="t-params-&gt;map-keys" classname=[snip]

Maybe logging to a file will work from the REPL, but there's not option to log to a file when configuring lein-eftest as far as I can see.

I can maybe throw together a PR this week if you have a preferred solution in mind.

NPE when running test suite on Clojure 1.8+, probably related to #63

I first saw this when I ran the test suite with Clojure 1.10 on a lark, when I was working on something else. But then, when I upgraded my project to the latest release (0.5.6, incorporating #63) I started seeing it as part of every run of my project’s test suite:

$ clojure -A:test:test/run

53/53   100% [==================================================]  ETA: 00:00
Exception in thread "main" java.lang.NullPointerException
	at clojure.lang.Numbers.ops(Numbers.java:1068)
	at clojure.lang.Numbers.add(Numbers.java:153)
	at eftest.report.pretty$eval2315$fn__2317.invoke(pretty.clj:150)
	at clojure.lang.MultiFn.invoke(MultiFn.java:229)
	at eftest.report.progress$eval2403$fn__2404.invoke(progress.clj:65)
	at clojure.lang.MultiFn.invoke(MultiFn.java:229)
	at fc4.test_runner.runner$multi_report$fn__3069.invoke(runner.clj:23)
	at clojure.test$do_report.invokeStatic(test.clj:357)
	at clojure.test$do_report.invoke(test.clj:351)
	at eftest.runner$run_tests.invokeStatic(runner.clj:202)
	at eftest.runner$run_tests.invoke(runner.clj:166)
	at fc4.test_runner.runner$run_tests.invokeStatic(runner.clj:53)
	at fc4.test_runner.runner$run_tests.invoke(runner.clj:51)
	at fc4.test_runner.runner$_main.invokeStatic(runner.clj:56)
	at fc4.test_runner.runner$_main.invoke(runner.clj:55)
	at clojure.lang.AFn.applyToHelper(AFn.java:152)
	at clojure.lang.AFn.applyTo(AFn.java:144)
	at clojure.lang.Var.applyTo(Var.java:705)
	at clojure.core$apply.invokeStatic(core.clj:665)
	at clojure.main$main_opt.invokeStatic(main.clj:491)
	at clojure.main$main_opt.invoke(main.clj:487)
	at clojure.main$main.invokeStatic(main.clj:598)
	at clojure.main$main.doInvoke(main.clj:561)
	at clojure.lang.RestFn.applyTo(RestFn.java:137)
	at clojure.lang.Var.applyTo(Var.java:705)
	at clojure.main.main(main.java:37)

I wanted to debug this a little, maybe even figure out how to fix it. So I added some Leiningen profiles to my local checkout of eftest, one for each of Clojure 1.8, 1.9, and 1.10. When I run lein test and the tests are run on Clojure 1.7, everything looks fine. But when I run lein with-profile 1.8 test (or 1.9 or 1.10) I get the same exception, with a longer stacktrace:

Longer stacktrace
...
lein test :only eftest.runner-test/test-fail-multi

ERROR in (test-fail-multi) (Numbers.java:1068)
Uncaught exception, not in assertion.
expected: nil
actual: java.lang.NullPointerException: null
 at clojure.lang.Numbers.ops (Numbers.java:1068)
    clojure.lang.Numbers.add (Numbers.java:153)
    eftest.report.pretty$eval3044$fn__3046.invoke (pretty.clj:151)
    clojure.lang.MultiFn.invoke (MultiFn.java:229)
    eftest.report.progress$eval3132$fn__3133.invoke (progress.clj:65)
    clojure.lang.MultiFn.invoke (MultiFn.java:229)
    clojure.test$do_report.invokeStatic (test.clj:357)
    clojure.test$do_report.invoke (test.clj:351)
    eftest.runner$run_tests.invokeStatic (runner.clj:202)
    eftest.runner$run_tests.invoke (runner.clj:166)
    eftest.runner_test$test_run_tests$fn__3349.invoke (runner_test.clj:36)
    eftest.runner_test$with_test_out_str_STAR_$fn__3341.invoke (runner_test.clj:22)
    eftest.runner_test$with_test_out_str_STAR_.invokeStatic (runner_test.clj:21)
    eftest.runner_test$with_test_out_str_STAR_.invoke (runner_test.clj:19)
    eftest.runner_test$test_run_tests.invokeStatic (runner_test.clj:36)
    eftest.runner_test$test_run_tests.invoke (runner_test.clj:30)
    eftest.runner_test$test_run_tests.invokeStatic (runner_test.clj:32)
    eftest.runner_test$test_run_tests.invoke (runner_test.clj:30)
    eftest.runner_test$fn__3366.invokeStatic (runner_test.clj:55)
    eftest.runner_test/fn (runner_test.clj:53)
    clojure.test$test_var$fn__9707.invoke (test.clj:717)
    clojure.test$test_var.invokeStatic (test.clj:717)
    clojure.test$test_var.invoke (test.clj:708)
    clojure.test$test_vars$fn__9733$fn__9738.invoke (test.clj:735)
    clojure.test$default_fixture.invokeStatic (test.clj:687)
    clojure.test$default_fixture.invoke (test.clj:683)
    clojure.test$test_vars$fn__9733.invoke (test.clj:735)
    clojure.test$default_fixture.invokeStatic (test.clj:687)
    clojure.test$default_fixture.invoke (test.clj:683)
    clojure.test$test_vars.invokeStatic (test.clj:731)
    clojure.test$test_all_vars.invokeStatic (test.clj:737)
    clojure.test$test_ns.invokeStatic (test.clj:758)
    clojure.test$test_ns.invoke (test.clj:743)
    user$eval224$fn__285.invoke (form-init4797442981940918597.clj:1)
    clojure.lang.AFn.applyToHelper (AFn.java:156)
    clojure.lang.AFn.applyTo (AFn.java:144)
    clojure.core$apply.invokeStatic (core.clj:667)
    clojure.core$apply.invoke (core.clj:660)
    leiningen.core.injected$compose_hooks$fn__154.doInvoke (form-init4797442981940918597.clj:1)
    clojure.lang.RestFn.applyTo (RestFn.java:137)
    clojure.core$apply.invokeStatic (core.clj:665)
    clojure.core$apply.invoke (core.clj:660)
    leiningen.core.injected$run_hooks.invokeStatic (form-init4797442981940918597.clj:1)
    leiningen.core.injected$run_hooks.invoke (form-init4797442981940918597.clj:1)
    leiningen.core.injected$prepare_for_hooks$fn__159$fn__160.doInvoke (form-init4797442981940918597.clj:1)
    clojure.lang.RestFn.applyTo (RestFn.java:137)
    clojure.lang.AFunction$1.doInvoke (AFunction.java:31)
    clojure.lang.RestFn.invoke (RestFn.java:408)
    clojure.core$map$fn__5851.invoke (core.clj:2755)
    clojure.lang.LazySeq.sval (LazySeq.java:42)
    clojure.lang.LazySeq.seq (LazySeq.java:51)
    clojure.lang.Cons.next (Cons.java:39)
    clojure.lang.RT.boundedLength (RT.java:1788)
    clojure.lang.RestFn.applyTo (RestFn.java:130)
    clojure.core$apply.invokeStatic (core.clj:667)
    clojure.test$run_tests.invokeStatic (test.clj:768)
    clojure.test$run_tests.doInvoke (test.clj:768)
    clojure.lang.RestFn.applyTo (RestFn.java:137)
    clojure.core$apply.invokeStatic (core.clj:665)
    clojure.core$apply.invoke (core.clj:660)
    user$eval224$fn__297$fn__330.invoke (form-init4797442981940918597.clj:1)
    user$eval224$fn__297$fn__298.invoke (form-init4797442981940918597.clj:1)
    user$eval224$fn__297.invoke (form-init4797442981940918597.clj:1)
    user$eval224.invokeStatic (form-init4797442981940918597.clj:1)
    user$eval224.invoke (form-init4797442981940918597.clj:1)
    clojure.lang.Compiler.eval (Compiler.java:7176)
    clojure.lang.Compiler.eval (Compiler.java:7166)
    clojure.lang.Compiler.load (Compiler.java:7635)
    clojure.lang.Compiler.loadFile (Compiler.java:7573)
    clojure.main$load_script.invokeStatic (main.clj:452)
    clojure.main$init_opt.invokeStatic (main.clj:454)
    clojure.main$init_opt.invoke (main.clj:454)
    clojure.main$initialize.invokeStatic (main.clj:485)
    clojure.main$null_opt.invokeStatic (main.clj:519)
    clojure.main$null_opt.invoke (main.clj:516)
    clojure.main$main.invokeStatic (main.clj:598)
    clojure.main$main.doInvoke (main.clj:561)
    clojure.lang.RestFn.applyTo (RestFn.java:137)
    clojure.lang.Var.applyTo (Var.java:705)
    clojure.main.main (main.java:37)
 

So I checked out line 150 of pretty.clj and saw this:

149 (defmethod report :summary [{:keys [test pass fail error duration]}]
150   (let [total (+ pass fail error)

I figured that one of pass | fail | error was not in the input map.

So I mangled the method so I could do some println debugging, and I saw that indeed, when the NPE is thrown, the value of the input map is something like {:type :summary, :duration 8.326198} — so it’s missing all three keys (:pass, :fail, and :error).

That’s as far as I got. I have no ideas as to why the input map would sometimes be missing those keys, and why that would appear to occur on Clojure 1.8+ but not 1.7.

Any ideas? I’d be happy to try to contribute a fix, if I could get some help with the debugging.

Locks up (usually) when there are more namespaces than threads

This happens when "multithread namespaces" is on.

In VisualVM, I see that all executer threads are parked, waiting on .get of FutureTask.

Given the stack traces, I'm confident that the problem is that every executer thread is trying to run a namespace in parallel, submitting back to the executer, but there are no threads left in the executer to run tests.

Note that this means that a fair number of threads are idle while running the tests.

Work-around: for now, disable multithread namespaces.
A possible solution: Use a separate thread pool with no limit (Executors/newCachedThreadPool) for running namespaces. Or somehow coordinate differently?

Catch output for successful tests

Some test runners – like pytest – show whatever a test would print to stdout only when the test fails. This is helpful when dealing with large, noisy test suites. For example, I encountered a test suite that printed hundreds of lines of stack traces even when every tests passed. It's hard to find the failing test out of that noise.

I'd like to have this feature in Eftest as well and I'd be happy to implement it. What do you think?

One hurdle is that programs can print stuff in a bunch of ways and there's no fool-proof way to catch them all. My suggestion is to just catch whatever goes to *out*, and maybe investigate what can be done with System/setOut. I think this should cover a lot of cases already.

Support for running a single test from command line

With lein test I can run a single test with a command like lein test :only foo.bar/baz. As far as I can tell, lein eftest only supports running tests for entire namespaces. Is there support for running a single test and if so, how can I do it?

PS. Thanks for this excellent library, I think this is the most complete clojure test runner that I encountered so far!

Datomic db values (and other large potentially-expandable values) produce a horrific console spew if included in test failure data

Using e.g. Datomic's support for transient in-memory databases in tests, along with test.check's property-based testing and (I strongly suspect) the failure data added by tools like test.chuck's for-all macro produces a perfect storm with eftest. Unlike lein test or other tools (including Calva's REPL), if the output happens to contain a Datomic DB, it will print out all the data in that. Even for a transient DB, that's a staggering amount, thousands of lines.

Representative:

(ns sample-test
  (:require
   [clojure.test.check.clojure-test :refer [defspec]]
   [clojure.test.check.generators :as gen]
   [com.gfredericks.test.chuck.properties :refer [for-all]]
   [datomic.api :as d]))

(defn test-state-db []
  (let [schemas [] ; Concatenation of relevant schemas omitted
        conn-str (str "datomic:mem://" (random-uuid))
        _ (d/create-database conn-str)
        conn (d/connect conn-str)]
    @(d/transact conn schemas)
    (d/db conn)))

(defn db-dependent-gen "Generator notionally based on database value" [db]
  gen/any)

(defspec test-db-things
  (let [base-db (test-state-db)]
    (for-all
     [v1 gen/any ; Something sensible
      :let [txns [] ; Various test-specific transactions based on v1 etc
            post-tx-db (:db-after (d/with base-db txns))]
      v2 (db-dependent-gen post-tx-db)]
     (not= v1 v2))))

The output of lein test :only sample-test/test-db-things is something like this:

FAIL in (test-db-things) (sample_test.clj:19)
expected: {:result true}
  actual: {:shrunk
           {:total-nodes-visited 20,
            :depth 9,
            :pass? false,
            :result false,
            :result-data nil,
            :time-shrinking-ms 8,
            :smallest
            [{v1 [],
              txns [],
              post-tx-db datomic.db.Db@1ac0e28c,
              v2 []}]},
           :failed-after-ms 4,
           :num-tests 1,
           :seed 1679008946391,
           :fail
           [{v1 (),
             txns [],
             post-tx-db datomic.db.Db@97460d9e,
             v2 ()}],
           :result false,
           :result-data nil,
           :failing-size 0,
           :pass? false,
           :test-var "test-db-things"}

Ran 1 tests containing 1 assertions.
1 failures, 0 errors.

The output of eftest for that is in the hundreds of kilobytes.

Calva solved a very similar problem without, I believe any Datomic-specific special-casing.

Double-count issue when using two reporters

I'm attempting to use a custom reporter to report results to both junit and the pretty-printer.

What I've found is that this will double-count the number of assertions and failures. For example:

    Ran 5 tests in 6.059 seconds
    10 assertions, 2 failures, 2 errors.

(Should be 1 assertion per test for 5 total. 1 failure and 1 error.)

A work-around suggested by @miikka is binding clojure.test/*report-counters* to nil for one of the reports:

    (defn report [m]
      (pretty/report m)
      (binding [clojure.test/*report-counters* nil]
        (xml-report m)))

Which works.

Is there a more proper way of handling this?

Multi-threaded tests generates invalid XML

With multithread? set to non-falsy, the XML appears to be mangled (perhaps race condition writing?)

This is what I see:

<testsuites><testsuite<testsuite<testsuite<testsuite<testsuite

Return test results rather than nil

Hi James,

I'm interested in using eftest during CI, which would mean I need to know if tests have failed. With that information I can exit with a non-zero status etc.

Would you be open to returning a map that describes the test run rather than nil in order to make this possible?

Support for clojure 1.9 specs ?

Hello,

I have a project with the following Lein dependencies:

:dependencies [[org.clojure/clojure "1.9.0-alpha17"]
                 [org.clojure/core.match "0.3.0-alpha5"]
                 [eftest "0.3.1"]]

If I try to use eftest in the REPL, I get

grape.core=> (require '[eftest.runner :as et])

CompilerException clojure.lang.ExceptionInfo: Call to clojure.core/ns did not conform to spec:
In: [2 0] val: import fails spec: :clojure.core.specs.alpha/ns-refer-clojure at: [:args :clauses :refer-clojure :clause] predicate: #{:refer-clojure}
In: [2 0] val: import fails spec: :clojure.core.specs.alpha/ns-require at: [:args :clauses :require :clause] predicate: #{:require}
In: [2 0] val: import fails spec: :clojure.core.specs.alpha/ns-import at: [:args :clauses :import :clause] predicate: #{:import}
...

Same thing with

grape.core=> (require '[eftest.runner :refer [find-tests run-tests]])

CompilerException clojure.lang.ExceptionInfo: Call to clojure.core/ns did not conform to spec:
In: [2 0] val: import fails spec: :clojure.core.specs.alpha/ns-refer-clojure at: [:args :clauses :refer-clojure :clause] predicate: #{:refer-clojure}
In: [2 0] val: import fails spec: :clojure.core.specs.alpha/ns-require at: [:args :clauses :require :clause] predicate: #{:require}
...

I am a Clojure newbie, but my understanding is that eftest needs some work to be compliant with Clojure spec introduced in Clojure 1.9. Is this correct?

And thanks for eftest, I really like the readability!

nondeterministic execution order of tests

Between separate runs of my tests, I'm seeing them execute in a different order although the default execution order for JUnit is purported to be "deterministic but not predictable". Any way to get eftest to behave the same way?

Support for selectors in the repl?

I would quite like to run all tests, excluding some integration tests from the repl.

At the moment it looks like all of the selector logic is in the lein plugin. Would it be possible to move the filtering logic into the repl side, even if the selector configuration needs to stay in the plugin?

(also: thanks for making this, it's great!)

JDK 11 support

eftest fails on JDK 11 since it uses fipp which in turn uses core.rrb-vector which has JDK 11 related compilation errors. This has been fixed in core.rrb-vector master branch and there is an upstream issue in fipp to make sure it's updated. I am opening this here as a reminder issue so that eftest can be updated. Currently this blocks JDK 11 testing in boot since it depends on eftest.

Upstream issue : brandonbloom/fipp#50
eftest JDK 11 failure : https://travis-ci.org/tirkarthi/eftest/jobs/402075270
core.rrb-vector issue : https://dev.clojure.org/jira/browse/CRRBV-18

Thanks

Wrong class on GitHub README

Th JUnit plugin is

         :report eftest.report.junit/report

And not:

          :report clojure.report.junit/report

as it currently appears on the README.md. :-)

Wrong failure reporting

First of all, thanks for this great tool.

With lein-eftest 0.4.3 I get this, which is what I am expecting:

$ lein eftest

54/54   100% [==================================================]  ETA: 00:00

Ran 54 tests in 0.184 seconds
55 assertions, 0 failures, 0 errors.

However, with lein-eftest 0.5.0 I get this:

$ lein eftest

30/54    55% [===========================                       ]  ETA: 00:00FAIL in boodle.api.resources.saving-test/insert-test (saving_test.clj:27)
30/54    55% [===========================                       ]  ETA: 00:00Testing insert saving resource
51/54    94% [===============================================   ]  ETA: 00:00expected: {:amount "3,5", :item "test"}
  actual: {:amount 3.5, :item "test"}
    diff: - {:amount "3,5"}
          + {:amount 3.5}

54/54   100% [==================================================]  ETA: 00:00

Ran 54 tests in 0.230 seconds
55 assertions, 1 failure, 0 errors.
Tests failed.

The code I am testing is here, if you want more details: https://github.com/manuel-uberti/boodle/blob/master/test/clj/boodle/api/resources/saving_test.clj

Add more description and rationale to readme

I was confused about what this is. I think it would be very helpful if you added a sentence near the top of the readme explaining that this is intended for running your tests from the REPL, as opposed to running lein test from the shell, presumably for the purpose of avoiding lein start-up time.

Btw, this looks great. Looking forward to trying it out. Thanks!

Report doesn't print a diff when used with Ultra

Actual:

FAIL in foo-test/bar-test (foo_test.clj:10)
expected: {:a 0, :b 1}
  actual: ({:b 1, :c 2})

Expected:

FAIL in foo-test/bar-test (foo_test.clj:10)
expected: {:a 0, :b 1}
  actual: {:b 1, :c 2}

    diff: - {:a 0}
          + {:c 2}

`lein eftest` fails with, "java.lang.ClassCastException: eftest.runner$synchronize$fn__2667 cannot be cast to clojure.lang.MultiFn"

Hi,

I just found eftest and tried to use it with a library I'm writing. lein eftest threw a ClassCastException as follows:

➜  liblevenshtein-clj git:(master) ✗ lein eftest                                                                                                                                                                             git:(master|✚1…

ERROR in liblevenshtein.distance-test/test-conformity-of-str->key)
Uncaught exception, not in assertion.
expected: nil
  actual:
java.util.concurrent.ExecutionException: java.lang.ClassCastException: eftest.runner$synchronize$fn__2667 cannot be cast to clojure.lang.MultiFn, compiling:(clojure/test/check/clojure_test.cljc:95:1)
clojure.lang.Compiler$CompilerException: java.lang.ClassCastException: eftest.runner$synchronize$fn__2667 cannot be cast to clojure.lang.MultiFn, compiling:(clojure/test/check/clojure_test.cljc:95:1)
           java.lang.ClassCastException: eftest.runner$synchronize$fn__2667 cannot be cast to clojure.lang.MultiFn
                           clojure.core/get-method                 core.clj: 1809
          clojure.test.check.clojure-test/eval5158        clojure_test.cljc:   95
                                               ...
                              clojure.core/load/fn                 core.clj: 6046
                                 clojure.core/load                 core.clj: 6045
                                 clojure.core/load                 core.clj: 6029
                                               ...
                             clojure.core/load-one                 core.clj: 5848
                          clojure.core/load-lib/fn                 core.clj: 5888
                             clojure.core/load-lib                 core.clj: 5887
                             clojure.core/load-lib                 core.clj: 5868
                                               ...
                                clojure.core/apply                 core.clj:  659
                            clojure.core/load-libs                 core.clj: 5925
                            clojure.core/load-libs                 core.clj: 5909
                                               ...
                                clojure.core/apply                 core.clj:  659
                              clojure.core/require                 core.clj: 5947 (repeats 2 times)
                                               ...
       clojure.test.check/eval5121/loading--auto--               check.cljc:   10
                       clojure.test.check/eval5121               check.cljc:   10
                                               ...
                              clojure.core/load/fn                 core.clj: 6046
                                 clojure.core/load                 core.clj: 6045
                                 clojure.core/load                 core.clj: 6029
                                               ...
                             clojure.core/load-one                 core.clj: 5848
                          clojure.core/load-lib/fn                 core.clj: 5888
                             clojure.core/load-lib                 core.clj: 5887
                             clojure.core/load-lib                 core.clj: 5868
                                               ...
                                clojure.core/apply                 core.clj:  659
                            clojure.core/load-libs                 core.clj: 5925
                            clojure.core/load-libs                 core.clj: 5909
                                               ...
                                clojure.core/apply                 core.clj:  659
                              clojure.core/require                 core.clj: 5947 (repeats 2 times)
                                               ...
                   clojure.spec.gen.alpha/dynaload                alpha.clj:   19
                         clojure.spec.gen.alpha/fn                alpha.clj:   26
                                               ...
                                clojure.core/deref                 core.clj: 2312
                clojure.spec.gen.alpha/quick-check                alpha.clj:   29
                clojure.spec.gen.alpha/quick-check                alpha.clj:   27
                                               ...
                                clojure.core/apply                 core.clj:  661
               clojure.spec.test.alpha/quick-check                alpha.clj:  309
                   clojure.spec.test.alpha/check-1                alpha.clj:  335
                  clojure.spec.test.alpha/check/fn                alpha.clj:  411
                           clojure.core/pmap/fn/fn                 core.clj: 6942
               clojure.core/binding-conveyor-fn/fn                 core.clj: 2022
                                               ...
               java.util.concurrent.FutureTask.run          FutureTask.java:  266
 java.util.concurrent.ThreadPoolExecutor.runWorker  ThreadPoolExecutor.java: 1149
java.util.concurrent.ThreadPoolExecutor$Worker.run  ThreadPoolExecutor.java:  624
                              java.lang.Thread.run              Thread.java:  748


1/1   100% [==================================================]  ETA: 00:00

Ran 1 tests in 0.323 seconds
1 assertion, 0 failures, 1 error.
Tests failed.

My library is currently very simple, with a single src file and a single test file. Both, along with my project.clj and ~/.lein/profiles.clj are listed below:

~/.lein/profiles.clj
{:user {:dependencies [[criterium "0.4.4"]
                       [alembic "0.3.2"]
                       [org.clojure/tools.nrepl "0.2.12"]]
        :plugins [
                  [cider/cider-nrepl "0.15.1"]
                  [jonase/eastwood "0.2.5"]
                  [lein-ancient "0.6.15"]
                  [lein-auto "0.1.3"]
                  [lein-bikeshed "0.5.0"]
                  [lein-cloverage "1.0.10"]
                  [lein-eftest "0.4.1"]
                  [lein-exec "0.3.7"]
                  [lein-kibit "0.1.6" :exclusions [org.clojure/clojure]]
                  [lein-midje "3.2.1"]
                  [lein-tarsier "0.10.0"]
                  [lein-vanity "0.2.0"]
                  [leinjacker "0.4.2"]
                  [org.clojars.kurtharriger/lein-depgraph "0.1.0"]
                  [re-frame/lein-template "0.3.2"]
                  [refactor-nrepl "2.3.1"]
                  [venantius/ultra "0.5.2" :exclusions [org.clojure/clojure
                                                        instaparse]]
                  [vimclojure/server "2.3.6" :exclusions [org.clojure/clojure]]
                  ]}}
project.clj
(defproject liblevenshtein "3.0.0"
  :description "A library for spelling-correction based on Levenshtein Automata."
  :url "https://github.com/universal-automata/liblevenshtein-clj"
  :license {:name "MIT"
            :url "https://raw.githubusercontent.com/universal-automata/liblevenshtein-clj/master/LICENSE"}
  :dependencies [[org.clojure/clojure "1.9.0"]]
  :profiles {:dev {:dependencies [[org.clojure/test.check "0.9.0"]]}}
  :source-paths ["src/clj"]
  :test-paths ["test/clj"])
src/clj/liblevenshtein/distance.clj
(ns liblevenshtein.distance
  (:require [clojure.spec.alpha :as s]))

(defn str->key [v w]
  (if (neg? (compare v w))
    [v w]
    [w v]))

(s/fdef str->key
        :args (s/cat :v string? :w string?)
        :ret (s/coll-of string? :kind vector? :count 2 :into [])
        :fn (fn [{[v w] :ret}]
              (<= (compare v w) 0)))
test/clj/liblevenshtein/test_distance.clj
(ns liblevenshtein.distance-test
  (:require [liblevenshtein.distance :as sut]
            [clojure.spec.test.alpha :as st]
            [clojure.test :as t]))

(t/deftest test-conformity-of-str->key
  (let [results (st/check `sut/str->key)
        summary (st/summarize-results results)
        {:keys [total check-passed]} summary]
    (t/is (= total check-passed))))

lein test does not fail with an exception:

➜  liblevenshtein-clj git:(master) ✗ lein test                                                                                                                                                                               git:(master|✚1…

Testing liblevenshtein.distance-test
{:sym liblevenshtein.distance/str->key}

Ran 1 tests containing 1 assertions.
0 failures, 0 errors.

This issue might be related to one reported against Leiningen: technomancy/leiningen#2173

Bonus error from eftest

I'm getting an error when I run lein eftest that I don't see from just lein test. I've set :eftest {:multithread? false}, any ideas for what else this could be please? This project uses clojure.spec.alpha, it's possible I made a mistake in my spec which is the ultimate root cause. In this case - well done eftest for finding it when lein test didn't, but please can you be more helpful about where the issue was? My code doesn't appear in the stack trace at all. I can't absolutely rule out test ordering issues but I'd be Very Surprised. Our tests just aren't that complicated, there aren't any atoms or use of @.

φ tempest 189.3 *=% lein eftest                                                                                                                                                                                                                                                                                                                                                                           ~/w/ccm/library/ccm-spec 13:06:22

ERROR in ccm.plaza-test/current-gen-test (FutureTask.java:122)           
Uncaught exception, not in assertion.

java.util.concurrent.ExecutionException: Syntax error compiling at (clojure/test/check/clojure_test.cljc:95:1).
clojure.lang.Compiler$CompilerException: Syntax error compiling at (clojure/test/check/clojure_test.cljc:95:1).
    data: #:clojure.error{:phase :compile-syntax-check,
                          :line 95,
                          :column 1,
                          :source "clojure/test/check/clojure_test.cljc"}
           java.lang.ClassCastException: eftest.runner$synchronize$fn__2824 cannot be cast to clojure.lang.MultiFn
                           clojure.core/get-method                 core.clj: 1817
          clojure.test.check.clojure-test/eval6223        clojure_test.cljc:   95
                                               ...                               
                              clojure.core/load/fn                 core.clj: 6126
                                 clojure.core/load                 core.clj: 6125
                                 clojure.core/load                 core.clj: 6109
                                               ...                               
                             clojure.core/load-one                 core.clj: 5908
                          clojure.core/load-lib/fn                 core.clj: 5948
                             clojure.core/load-lib                 core.clj: 5947
                             clojure.core/load-lib                 core.clj: 5928
                                               ...                               
                                clojure.core/apply                 core.clj:  667
                            clojure.core/load-libs                 core.clj: 5985
                            clojure.core/load-libs                 core.clj: 5969
                                               ...                               
                                clojure.core/apply                 core.clj:  667
                              clojure.core/require                 core.clj: 6007 (repeats 2 times)
                                               ...                               
       clojure.test.check/eval6186/loading--auto--               check.cljc:   10
                       clojure.test.check/eval6186               check.cljc:   10
                                               ...                               
                              clojure.core/load/fn                 core.clj: 6126
                                 clojure.core/load                 core.clj: 6125
                                 clojure.core/load                 core.clj: 6109
                                               ...                               
                             clojure.core/load-one                 core.clj: 5908
                          clojure.core/load-lib/fn                 core.clj: 5948
                             clojure.core/load-lib                 core.clj: 5947
                             clojure.core/load-lib                 core.clj: 5928
                                               ...                               
                                clojure.core/apply                 core.clj:  667
                            clojure.core/load-libs                 core.clj: 5985
                            clojure.core/load-libs                 core.clj: 5969
                                               ...                               
                                clojure.core/apply                 core.clj:  667
                              clojure.core/require                 core.clj: 6007 (repeats 2 times)
                                               ...                               
                   clojure.spec.gen.alpha/dynaload                alpha.clj:   19
                         clojure.spec.gen.alpha/fn                alpha.clj:   26
                                               ...                               
                                clojure.core/deref                 core.clj: 2320
                clojure.spec.gen.alpha/quick-check                alpha.clj:   29
                clojure.spec.gen.alpha/quick-check                alpha.clj:   27
                                               ...                               
                                clojure.core/apply                 core.clj:  669
               clojure.spec.test.alpha/quick-check                alpha.clj:  309
                   clojure.spec.test.alpha/check-1                alpha.clj:  335
                  clojure.spec.test.alpha/check/fn                alpha.clj:  411
                           clojure.core/pmap/fn/fn                 core.clj: 7022
               clojure.core/binding-conveyor-fn/fn                 core.clj: 2030
                                               ...                               
               java.util.concurrent.FutureTask.run          FutureTask.java:  266
 java.util.concurrent.ThreadPoolExecutor.runWorker  ThreadPoolExecutor.java: 1149
java.util.concurrent.ThreadPoolExecutor$Worker.run  ThreadPoolExecutor.java:  624
                              java.lang.Thread.run              Thread.java:  748

39/39   100% [==================================================]  ETA: 00:00

Ran 39 tests in 0.252 seconds
172 assertions, 0 failures, 1 error.
Tests failed.
φ tempest 189.3 *=% lein test                                                                                                                                                                                                                                                                                                                                                                             ~/w/ccm/library/ccm-spec 13:06:30

Testing ccm.plaza-test
Success!

Ran 39 tests containing 172 assertions.
0 failures, 0 errors.

Error when using JDK11

Hi, thank you for this awesome library!

I'm having some trouble after upgrading to java 11 and clojure 1.10.0.rc-4. I can't run lein test or lein eftest, and instead I get the following stacktrace:

16:06:42.723 INFO  medino-web.handler - Selmer template cache is OFF.
Exception in thread "main" java.lang.ExceptionInInitializerError
	at clojure.main.<clinit>(main.java:20)
Caused by: Syntax error compiling deftype* at (clojure/core/rrb_vector/rrbt.clj:282:1).
	at clojure.lang.Compiler.analyzeSeq(Compiler.java:7114)
	....
	at clojure.lang.RT.loadResourceScript(RT.java:368)
	at clojure.lang.RT.maybeLoadResourceScript(RT.java:364)
	at clojure.lang.RT.doInit(RT.java:485)
	at clojure.lang.RT.<clinit>(RT.java:338)
	... 1 more
Caused by: java.lang.IllegalArgumentException: Must hint overloaded method: toArray
	at clojure.lang.Compiler$NewInstanceMethod.parse(Compiler.java:8496)
	at clojure.lang.Compiler$NewInstanceExpr.build(Compiler.java:8058)
	at clojure.lang.Compiler$NewInstanceExpr$DeftypeParser.parse(Compiler.java:7934)
	at clojure.lang.Compiler.analyzeSeq(Compiler.java:7106)
	... 244 more
Tests failed.

I believe this is caused by this bug in core.rrb-vector.: https://dev.clojure.org/jira/browse/CLJ-2374
which is a dependency of puget.

Putting [mvxcvi/puget "1.0.3"] in my dependency list resolves the issue, so I belive upgrading that in the project.clj files should resolve the issue.

Happy to make a pull request if that helps at all.
Thanks!

Run a single test?

Is it possible to run a single test? With standard Leiningen testing, this is easy:

lein test :only my.ns/test-var

However, eftest seems to get confused when specifying a var:

$ lein eftest :only my.ns/test-var
No tests found.
$ lein eftest my.ns/test-var
Exception in thread "main" java.io.FileNotFoundException: Could not locate test_var__init.class or test_var.clj on classpath. Please check that namespaces with dashes use underscores in the Clojure file name., compiling:(/tmp/form-init7945984824390511054.clj:1:73)

fail-fast? not working

Hi. First of all, thank you for providing this awesome library, it has been a life saver for my team!

I can't seem to get the fail-fast? option to work when running tests from the repl like this:

(eftest/run-tests (eftest/find-tests "test")
                    {:multithread?    false
                     :report          eftest.report.pretty/report
                     :capture-output? true
                     :test-warn-time  500
                     :fail-fast?      true})

With this config, when a test fails it keeps going running all of them!

Getting this working would help me a lot, as running all my tests takes quite a long time when something funamental breaks (because so many errors are printed to the REPL).

Am I doing something wrong, or is this a real issue? I'm using [eftest "0.5.9"]

=== edit: Upgraded to 0.5.9 and the problem persists

Ability to override project-wide parallelism strategy

Currently there is no way to override the parallelism strategy defined in the project.clj. For example, say that we want the default behaviour to be:

{:eftest {:multithread? :namespaces}}

But for some namespaces, we want it to be

{:eftest {:multithread? :vars}}

That is, the project.clj's :eftest section to be override-able on namespace level, like :eftest/synchronized works for vars.

Option to stop on first failure

It would be quite nice to be able to run "until first failure", perhaps as a mode. Even better would be to start the next test run with said failure.

Shorten test runs using LPT algorithmn

Since running test in parallel is exactly the "Multiprocessor scheduling problem", sorting the jobs by last known run time, then running longest first, should shorten the test time significantly (and also make run time more stable).

Proposal: We add a defonce atom with a map from test symbol to last known runtime in milliseconds. Sort the tests by this with some arbitrary default value if missing before assigning to threads, and record run time to the atom as tests complete. The first test run will effectively work the same way as it does today, but subsequent test runs should complete earlier. As the atom is just a heuristic, it is OK for it to be out of date.

I'm willing to do the work here, but does this sound good?

Command line support?

We have an ANT task that currently runs our tests with a custom runner. Though I'd like to use something more standard and with prettier output. I was wondering if the output of eftest can be printed to out with color, or is this supposed to run from inside a REPL only?

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.