2013-06-01 12 views
28

Wie gehst du über Unit Testing Javascript, das das DOM verwendet und ändert?Unit Testing Javascript, das das DOM beinhaltet

Ich gebe ein einfaches Beispiel. Ein Formularvalidierer, der nach leeren Textfeldern sucht, die in JavaScript geschrieben sind und JQuery verwenden.

 function Validator() { 

     this.isBlank = function(id) { 
      if ($(id).val() == '') { 
       return true; 
      } else { 
       return false; 
      } 
     }; 

     this.validate = function(inputs) { 

      var errors = false; 

      for (var field in inputs) { 
       if (this.isBlank(inputs[field])) { 
        errors = true; 
        break; 
       } 
      } 

      return errors; 
     }; 
    } 

Verbrauch:

var validator = new Validator(); 
var fields = { field_1 : '#username', field_2 : '#email' }; 

if (!validator.validate(fields)) { 
    console.log('validation failed'); 
} else { 
    console.log('validation passed'); 
} 

Was ist die beste Praxis für so zu Unit-Test etwas versuchen?

+1

Auschecken PhantomJS. http://phantomjs.org/ – Brad

+0

Siehe auch [Testen der DOM-Manipulation im Jasmin-Test] (http://stackoverflow.com/questions/7672389/testing-dom-manipulating-in-jasmine-test) –

+0

.und CasperJs: http : //casperjs.org/ – kaore

Antwort

19

im Idealfall sollten Sie den Code teilen. Die Validierungslogik benötigt keinen DOM-Zugriff, also würden Sie dies in ihre eigene Funktion einfügen und die Logik, die die ID verarbeitet, in einen Wert setzen, der dann in einen anderen validiert wird.

Dadurch können Sie die Validierungslogik einfacher testen und bei Bedarf einen Funktionstest mit einigen der von Joseph the Dreamer vorgeschlagenen Tools durchführen.

+1

Dies ist absolut der Weg zu gehen. Die Interaktion mit dem DOM bedeutet in der Regel, dass Sie eher einen Funktions- oder Integrationstest durchführen. Platzieren Sie Ihren Validierungscode in einem separaten Modul mit eigenen Komponententests. Dann integrieren Sie das Modul mit Ihrem bevorzugten Modullader wie zB browserify https://github.com/substack/browserify – Noah

9

Sie können Qunit für Komponententests mit DOM verwenden. Wenn Sie es automatisieren möchten, können Sie Grunt mit grunt-contrib-qunit Aufgabe verwenden, die Ihre Seiten in einem kopflosen WebKit namens PhantomJS startet.

+2

Und hier ist ein Beispiel dafür, wie man das macht: http://Stackoverflow.com/a/4178173/507339 – Nilzor

9

In einem unwahrscheinlichen Fall, in dem der meiste JavaScript-Code Logik enthält und wenig jQuery-Code (oder Live-DOM-Elemente) verwendet, können Sie den Code so umgestalten, dass der Zugriff auf DOM/jQuery einfacher wird und der Test mit Mock-Implementierungen geschrieben wird :

function Validator(){ 
    this.getElementValue = function(id){return $(id).val();} 

    this.check_blank = function(id){ 
    if(this.getElementValue(id) == '') // replace direct call to jQuery mock-able call 
     return false; 
    else 
     return true; 
    }.... 
} 

Und in Test bieten Mock Umsetzung:

test("Basic valid field", function() { 
    var validation = new Validator(); 

    // replace element accessor with mock implementation: 
    validation.getElementValue = function(id){ 
    equals(id, "#my_field"); // assert that ID is expected one 
    return "7"; 
    } 
    var form_fields = {field_1 : '#my_field'}; 

    ok(validation.validate(form_fields), "non-empty field should be valid"); 
}