Wie schreibt man Komponententests für vorgeschlagene Pakete?

8

Pakete in R können verschiedene Arten von Abhängigkeiten von anderen Paketen haben. Einige dieser Typen geben harte Anforderungen an, d. H.% Co_de%, Depends und Imports .

Es gibt jedoch eine zweite Kategorie, die eine weichere Abhängigkeit anzeigt, d. h. LinkingTo und Suggests . In beiden Fällen bietet das Paket zusätzliche Funktionen, wenn das vorgeschlagene / erweiterte Paket verfügbar ist.

Hier ein konkretes Beispiel: Das Paket Enhances importiert checkpoint weil knitr knitr hilft, checkpoint files zu analysieren.

Aber jetzt überlege ich, rmarkdown in eine knitr Abhängigkeit zu ändern, d. h. stelle nur diese Funktionalität zur Verfügung, wenn Suggests tatsächlich installiert ist.

Für einen korrekten Komponententest bedeutet dies, dass ich beide Szenarien testen muss:

  1. Wenn knitr verfügbar ist, dann tu was.
  2. Wenn knitr nicht verfügbar ist, dann warnen Sie und machen Sie nichts.

Der eigentliche R-Code ist einfach:

%Vor%

Frage

Aber wie kann ich Komponententests für beide Szenarien einrichten?

So wie ich es sehe, wird die einfache Tatsache, nach knitr zu suchen, das require(knitr) -Paket laden, wenn es in der lokalen Bibliothek verfügbar ist.

Um also Fall 1 zu testen, muss ich knitr lokal installieren, was bedeutet, dass ich nicht nach Fall 2 testen kann.

Gibt es eine Möglichkeit, knitr (oder ein anderes Einheitentestframework) für diesen Anwendungsfall zu konfigurieren?

    
Andrie 12.01.2015, 17:40
quelle

1 Antwort

3

tl; dr

Um zu testen, welcher Zweig bei Verwendung von require(knitr) fehlschlägt, verwenden Sie trace() , um require() vorübergehend zu ändern, damit knitr nicht gefunden wird, auch wenn es in .libPaths() vorhanden ist. . Setzen Sie den Wert von require() im Körper von lib.loc= auf R.home() zurück - ein vorhandenes Verzeichnis, das kein knitr -Paket enthält.

Dies scheint in einem Paket genauso gut zu funktionieren wie in einer interaktiven Sitzung, in der Sie Folgendes ausführen:

%Vor%

Wenn ich das verstanden habe, haben Sie eine Funktion mit zwei Zweigen, von denen eine in R-Sitzungen ausgeführt werden soll, für die require(knitr) erfolgreich ist, und die andere in Sitzungen, in denen sie fehlschlägt. Sie möchten diese Funktion dann "in beide Richtungen" von einer einzigen R-Instanz testen, in der knitr tatsächlich auf .libPaths() steht.

Sie brauchen also eine Möglichkeit, um den Aufruf require(knitr) vorübergehend auf das tatsächliche Vorhandensein von knitr zu blenden. Das vollständige und zeitweilige Zurücksetzen des von .libPaths() zurückgegebenen Werts sah vielversprechend aus, scheint jedoch nicht möglich zu sein.

Ein weiterer vielversprechender Weg besteht darin, den Standardwert von lib.loc in Aufrufen von require() von NULL (was "Wert von .libPaths() verwendet") auf einen anderen Ort zurückzusetzen, wo knitr ist nicht verfügbar Sie können dies nicht erreichen, indem Sie base::require() oder (in einem Paket) überschreiben, indem Sie eine lokale Maskierungsversion von require() mit dem gewünschten Wert von lib.loc definieren.

Es sieht jedoch so aus, als könnten Sie trace() verwenden, um require() temporär zu modifizieren (blenden Sie die Verfügbarkeit von knitr ein, indem Sie lib.loc=R.home() setzen). Dann machen Sie untrace() , um require() auf die Vanilla-Version wiederherzustellen, die weitergeht und knitr findet.

So sah das in dem Dummy-Paket aus, mit dem ich es getestet habe. Zuerst eine R-Funktion, die es uns ermöglicht, den Erfolg entlang der beiden Zweige zu testen

%Vor%

Dann ein paar Tests, einen für jeden Zweig:

%Vor%

Um dies zu testen, habe ich pkgKitten::kitten("dummy") verwendet, um ein Quellverzeichnis zu erstellen, in diese beiden Dateien kopiert, Suggests: knitr zur Datei DESCRIPTION hinzugefügt und dann devtools::install() und devtools::check() vom entsprechenden Verzeichnis ausgeführt . Das Paket wird problemlos installiert und übergibt alle Prüfungen.

    
Josh O'Brien 13.01.2015, 17:23
quelle

Tags und Links