Hier ein Puzzlespiel. Ich habe ein lein-Plugin, das meinen clojure.test-Code manuell ausführt. Er deklariert eine dynamische Variable baseuri
, auf die ich innerhalb meiner Tests zugreifen möchte. Ich werde mich ausziehen und den Code ändern, um sofort zur Sache zu kommen. Hier, innerhalb meines Plugins, habe ich eine Konfigurationsdatei, die die dynamische baseuri
Variable erstellt und sie auf eine leere Zeichenfolge setzt.Verwenden einer dynamischen Variablenbindung in einem Leiningen-Plugin
;; myplugin
;; src/myplugin/config.clj
(ns leiningen.myplugin.config)
(def ^:dynamic baseuri "")
Eine Aufgabe, aus dem Plugin setzt die dynamischen baseuri
Variable und führt Tests mit clojure.test:
;; src/myplugin/runtests.clj
(ns leiningen.myplugin.runtests
(:require [leiningen.myplugin.config :as config]
[clojure.test]
[e2e.sometest]))
(defn run [project]
(binding [config/baseuri "https://google.com/"]
(println config/baseuri) ;; <-- prints google url
;; run clojure.test test cases from e2e.sometest namespace
;; This will call the `sampletest` test case
(clojure.test/run-tests e2e.sometest)
))
Und Innenseite meines clojure.test Ich versuche, die BaseUri Variable zu verwenden, aber die Bindung hält nicht. Sein Wert ist, was ich ursprünglich baseuri
erklärt (eine leere Zeichenkette)
;; tests/e2e/sometest.clj
(ns e2e.sometest
(:require [leiningen.myplugin.config :as config]))
(deftest sampletest
(println config/baseuri)) ;; <-- Prints an empty string instead of google url
Ich bin wirklich hier bei einem Verlust. Irgendwelche Erklärungen dafür, warum dies der Fall sein würde? Ich hatte die genaue gleichen Code funktioniert, wenn es als eigenständige Anwendung geschrieben wurde. Aber als ich es auf ein lein Plugin portierte, tauchte dieses bindende Problem auf. Ein ernsthafter Kopfkratzer.
EDIT
Ich erhalte Kommentare über die globale dynamische Variablen. Obwohl ich der Meinung bin, dass sich die Frage nicht rechtfertigen muss, werde ich Hintergrundinformationen liefern, in der Hoffnung, dass andere dem Programmierer mehr Sympathie entgegenbringen.
Der Zweck dieses Plugins ist es, skriptfähige und parallele Ausführung von e2e-Tests auf Remote-Service-Provider wie Saucen zu ermöglichen. Dies ist nicht möglich mit Vanille clojure.test
. Sie können die Konfiguration nicht über die Befehlszeile mit lein test
übergeben. Außerdem verwende ich clj-webdriver
für E2e-Tests und es ist nicht möglich, Testsuiten mehrmals parallel auf verschiedenen Plattformen mit clojure.test
zu laufen. Sowohl clojure.test
als auch clj-webdriver
erzwingen einen nicht funktionalen Code und erfordern, dass ich einige globale dynamische Variablen verwende. (Diese beiden Projekte verwenden Globals und sogar Namespace-Metadaten, ihre Lösungen zu zerhacken.)
Aber das Festigkeit, um eine projektweite baseuri
konfiguriert werden vom project.clj
und auch zu ermöglichen - da dies zu verstehen ist sein scriptable - Ich benötige, dass baseuri
mit einem Befehlszeilenargument zum Plugin überschrieben werden, wenn Sie es ausführen, muss ich die Variable aus dem Plugin setzen. Da die Variable vom Plugin gesetzt werden muss (von der Kommandozeile aus geparst) und ich keine Parameter an deftest
übergeben kann, ist meine Option eine dynamische Bindung. Für die funktionalen Puristen ist dies nur ein weiteres Beispiel dafür, dass das wirkliche Leben unordentlich ist.
Ich habe den Code bearbeitet, um in einer grundlegenden Weise zu zeigen, wie die clojure.test-Fälle ausgeführt werden. Ich gebe einfach den Namespace, der ausgeführt werden soll, an die Methode clojure.test/run-tests
weiter.
Das eigentliche Plugin ist ein paar hundert Zeilen Code mit Abstraktionen, Kommandozeilenanalyse, Namespace-Suche und eine ganze Reihe mehr. Aber was Sie hier sehen, sind die einzigen wichtigen Teile. Es werden keine Threads gestartet. Die Clojure-Testfälle heißen innerhalb des Bindungsbereichs und das alles funktioniert, wenn sie in einer eigenständigen Anwendung ausgeführt werden.Wenn der eigenständige e2e-Test-Runner in eine lein-Plugin-Aufgabe eingefügt wurde, scheint die Bindung irgendwie aus dem Rahmen zu fallen, obwohl sich der Code nicht geändert hat.
Können Sie uns zeigen, welcher Code genau an Stelle Ihres Kommentars steht ';; rennt clojure.test code here'? –
Ich habe meine Antwort bearbeitet, um zu zeigen, wie die clojure.test-Testfälle laufen. –