Open mmontone opened 4 years ago
There is currently no way to have parent test forms execute around child test instances.
The easiest way to do what you want is to wrap your test forms in a with-database
macro or something similar, or to define a wrapper around define-test
that does this.
You could also use the fixtures system by using define-fixture-capture
and define-fixture-restore
on symbols that name databases, and then annotating your tests with :fix (db-name)
.
I've managed to execute around tests with a custom class:
;; test class with setup/teardown support
(defclass around-test (parachute::test)
((setup :initarg :setup :accessor setup :initform nil)
(teardown :initarg :teardown :accessor teardown :initform nil))
(:documentation "Test class with setup/teardown support"))
(defmethod parachute::eval-in-context :around (context (test around-test))
(when (setup test)
(funcall (setup test)))
(unwind-protect
(call-next-method)
(when (teardown test)
(funcall (teardown test)))))
(defun create-db ()
(format t "Creating db.."))
(defun drop-db ()
(format t "Dropping db.."))
(parachute:define-test my-db-test
:test-class around-test
:setup create-db
:teardown drop-db
(parachute:true (= 1 1) "One is equal to one"))
(parachute:define-test child-db-test
:parent my-db-test
:description "Subtest"
(parachute:fail (error "An expected failure.") error "Expecting failure")
(parachute:fail (warn "An expected warning.") warning "Expecting warninge"))
(parachute:test 'my-db-test)
Result:
? COMMON-LISP-USER::MY-DB-TEST
Creating db..
0.000 ✔ (true (= 1 1))
? COMMON-LISP-USER::CHILD-DB-TEST
0.000 ✔ (fail (error "An expected failure.") error)
0.000 ✔ (fail (warn "An expected warning.") warning)
0.000 ✔ COMMON-LISP-USER::CHILD-DB-TEST
Dropping db..
0.001 ✔ COMMON-LISP-USER::MY-DB-TEST
;; Summary:
Passed: 3
Failed: 0
Skipped: 0
It would be nice to consider an extension similar to this perhaps?
I feel like an extension to the fixture framework would be the best place for something like this, since you are, in effect, fixing something in place for the duration of a test. I'll have to think on the details, though.
I'm not clear on the details but I think the MOP could help here, something to do with a new generic function type and/or method combination type, instead of some idiosyncratic and unintuitive API.
Has anything changed in the last year with the setup&teardown recommendations?
I'm afraid not. I haven't had any time to commit to this, and nobody else has stepped up to the challenge either :)
9d91cc9 changed fixtures such that they execute around children as well, allowing the suggested idea in https://github.com/Shinmera/parachute/issues/19#issuecomment-620070283 to work somewhat:
(define-fixture-capture database (name)
(when (database-p name)
(create-database name)))
(define-fixture-capture database (name)
(when (database-p name)
(drop-database name)))
(define-test database-tests
:fix (my-db))
(define-test child
:parent database-tests
...)
The only constraint right now is that fixtures are not inherited, meaning if you run the child
test directly, it will not trigger the fixture. I'll have to think about how to make that work.
Hello.
I'm thinking of using Parachute for testing my application.
I have a db that that I would like to recreate in some context. So, I'm thinking of having a parent test suite, that starts by creating the db (setUp), runs its children tests, and drops the db at the end (teardown).
So, it would be:
Is this possible? If so, how? (I've looked at fixtures, but I don't get them yet.)
Thanks!
Mariano