mocha.js के साथ कई फ़ाइलों से परीक्षण में शामिल होना


87

मैं एक फ़ाइल में कई फाइलों से सभी परीक्षणों में शामिल होने की कोशिश कर रहा हूं, कुछ इस तरह:

  describe('Controllers', function() {
    describe('messages.js', function() {
      require('./controllertests/messages').test(options);
    })
    describe('users.js', function() {
      require('./controllertests/users').test(options);
    })
  })

मुझे पूरा यकीन है कि यह परीक्षण में शामिल होने का सबसे अच्छा तरीका नहीं है, मुझे कुछ अलग-अलग उदाहरण मिल रहे हैं कि यह कैसे करना है: s


1
जिज्ञासु, परीक्षण को एक फ़ाइल में एक साथ शामिल करने की आवश्यकता क्यों है?
thgaskell

2
स्थानीय चर और संगठन साझा करने के लिए
coiso

यदि आप परीक्षण को प्रश्न में शामिल करते हैं तो यह अधिक समझ में आता है। ऐसा लगता है कि आप एकीकरण परीक्षणों (इकाई परीक्षणों के विपरीत) की ओर झुकाव कर रहे होंगे। आम तौर पर आपको परीक्षणों के दौरान चर साझा करने की आवश्यकता नहीं होनी चाहिए।
thgaskell

2
और बड़ा मुद्दा यह है कि मैं 1 huuuuge फ़ाइल की तुलना में 20 फाइलें पसंद करना चाहूंगा
coiso

2
इसके अलावा, अगर आप यह देखते हैं कि मोचा कैसे सूट्स को संभालता है, तो इसका कॉन्सेप्ट .only()उपयोगी हो सकता describe.only()है, फिर भी यह पूरी तरह से परीक्षण की एक डायरेक्ट्री चलाने में सक्षम हो सकता है । यही मुझे यहां लाया है।
क्रिस

जवाबों:


113

आप एक से अधिक मॉड्यूल शामिल करना चाहते हैं में अपने describeपदानुक्रम जैसे आप अपने सवाल में कर रहे हैं, तुम क्या कर रहे काफी है यह जब तक आप मोचा के लिए एक कस्टम परीक्षण लोडर लिखना चाहते हैं,। कस्टम लोडर को लिखना आसान नहीं होगा या आपके पास पहले से मौजूद कोड की तुलना में अधिक स्पष्ट नहीं होगा।

यहाँ एक उदाहरण है कि मैं कुछ चीजों को कैसे बदलूंगा। testइस उदाहरण में उपनिर्देशिका के रूप में आयोजित किया जाता है:

.
└── test
    ├── a
    │   └── a.js
    ├── b
    │   └── b.js
    ├── common.js
    └── top.js

top.js:

function importTest(name, path) {
    describe(name, function () {
        require(path);
    });
}

var common = require("./common");

describe("top", function () {
    beforeEach(function () {
       console.log("running something before each test");
    });
    importTest("a", './a/a');
    importTest("b", './b/b');
    after(function () {
        console.log("after all tests");
    });
});

importTestसमारोह सिर्फ शो कैसे यह पूरे फिर से लिखें बिना कई मॉड्यूल आयात करने की पुनरावृत्ति को संभालने के लिए संभव हो जाएगा करने के लिए है describe(... require...बात हर बार। commonमॉड्यूल धारण करने के लिए क्या आप टेस्ट स्वीट के कई मॉड्यूल में उपयोग करने की आवश्यकता होती है। मैं वास्तव में इसका उपयोग नहीं कर रहा हूं, topलेकिन जरूरत पड़ने पर इसका इस्तेमाल किया जा सकता है।

मैं यहाँ देखेंगे कि beforeEachऔर प्रत्येक से पहले अपने कोड चलेगा हर एक के साथ पंजीकृत परीक्षण itहै कि क्या वे अंदर दिखाई describeमेंtop या वे में प्रदर्शित आयातित मॉड्यूल के किसी भी । इसके साथ --recursive, beforeEachकोड को प्रत्येक मॉड्यूल में कॉपी करना होगा या शायद आपके पास beforeEachप्रत्येक मॉड्यूल में एक हुक होगा जो एक सामान्य मॉड्यूल से आयातित फ़ंक्शन को कॉल करता है।

इसके अलावा, afterहुक सभी के बाद चलेगा सूट में परीक्षणों के । इसके साथ दोहराया नहीं जा सकता --recursive। यदि आप प्रत्येक मॉड्यूल --recursiveके कोड का उपयोग करते हैं और जोड़ते हैं after, तो इसे पूरे परीक्षण के लिए केवल एक बार मॉड्यूल के बजाय एक बार निष्पादित किया जाएगा ।

सभी परीक्षण एकल के तहत दिखाई देते हैं top शीर्षक के हैं, का उपयोग करके दोहराया नहीं जा सकता --recursive--recursiveप्रत्येक फ़ाइल के साथ हो सकता है describe("top"लेकिन यह प्रत्येक फ़ाइल के लिए एक नया topशीर्षक बनाएगा ।

common.js:

var chai = require("chai");

var options = {
    foo: "foo"
};

exports.options = options;
exports.chai = chai;
exports.assert = chai.assert;

एक का उपयोग मॉड्यूल नामित commonइस तरह से बचने के लिए होने के लिए कुछ मैं अपने परीक्षण सूट में से कुछ में किया है हैrequire सामानों एक गुच्छा खत्म हो जाए और वैश्विक रीड-ओनली वेरिएबल्स या फ़ंक्शंस को पकड़ कर रखा जा सके जो राज्य नहीं रखते हैं। मुझे globalलगता है कि इस तरह से थैगास्केल के उत्तर में ऑब्जेक्ट को प्रदूषित नहीं करना है क्योंकि यह ऑब्जेक्ट वास्तव में वैश्विक है और यहां तक ​​कि तीसरे पक्ष के पुस्तकालयों में भी आपका कोड लोड हो रहा है। यह ऐसा कुछ नहीं है जो मुझे अपने कोड में स्वीकार्य लगे।

a/a.js:

var common = require("../common");
var options = common.options;
var assert = common.assert;

it("blah a", function () {
    console.log(options.foo);
    assert.isTrue(false);
});

b/b.js:

it("blah b", function () {});

3
जबकि मैं मानता हूं कि आपको globalगुंजाइश को प्रदूषित नहीं करना चाहिए , मैं परीक्षण फ़ाइलों को साफ रखने के लिए मुखर पुस्तकालयों के लिए इसका उपयोग करता हूं। ऐसा नहीं है कि आप ओवर राइटिंग कर रहे हैं global.processglobalजब तक अन्य पुस्तकालय स्पष्ट रूप से कॉल global.XYZनहीं कर रहे हैं, जो संभावना नहीं है, स्थानीय चर खत्म हो जाएंगे । यह केवल परीक्षणों की अवधि तक रहता है। मुझे अभी तक चोट नहीं पहुंची है, लेकिन मैं आपको उस पल के बारे में
बताऊंगा

उदाहरण के लिए importTestऔर कॉल करने में क्या अंतर है require('path')()?
चेरीनर्ड

@CreasolDev importTestफ़ंक्शन केवल एक सुविधा फ़ंक्शन है। महत्वपूर्ण बात यह है कि requireकॉल को describeब्लॉक में लपेटना है । यह महत्वपूर्ण है कि requireकॉल को लपेटा जाए describeअन्यथा मॉड्यूल अपने स्वयं के ब्लॉक में अलग-थलग नहीं होंगे और आयातित फ़ाइल द्वारा निर्धारित किसी भी हुक को गलत ब्लॉक पर सेट किया जाएगा। यदि बिना लपेट के importTestसीधे कॉल के साथ प्रतिस्थापित किया गया था , तो मॉड्यूल और हुक साझा करेंगे। उदाहरण के लिए, एक हुक सेट प्रत्येक परीक्षण से पहले भी चलेगा । requiredescribea/ab/bbeforeEachb/ba/a
लुई

1
मैं आपके शीर्ष स्तर के वर्णन में पहले की तरह कोई तर्क नहीं चलाऊंगा। प्रत्येक फ़ाइल को "सामान" से पहले करने दें। यदि आप ऐसा करते हैं तो आप एक-दूसरे को अपने परीक्षणों को युग्मित करेंगे और असंबंधित कार्यान्वयन करेंगे।
पॉजिटिव

1
मैं उनकी संबंधित फाइलों में वर्णन के रैपिंग भी करूंगा, न कि importTest फंक्शन में। प्रत्येक संबंधित फ़ाइल में शीर्ष स्तर का वर्णन वैसे भी उनके परीक्षण सूट उद्देश्य का वर्णन करना चाहिए
पॉजिटिव

35

हालांकि यह सीधे सवाल से जुड़ा नहीं हो सकता है, मैं जिस उत्तर की तलाश कर रहा था वह था:

$ mocha --recursive

"परीक्षण" फ़ोल्डर की उप-निर्देशिकाओं में सभी परीक्षणों को निष्पादित करेगा। साफ। उन परीक्षणों की एक सूची बनाए रखने के लिए बचत करता है जिन्हें मैं लोड करना चाहता हूं और वास्तव में बस हमेशा सब कुछ चलाता हूं।


3
सबसे बढ़िया उत्तर! अन्य प्रस्तावित समाधानों की तुलना में बहुत सरल।
caiosm1005

12
@ caiosm1005 यह उत्तर वास्तव में ओपी द्वारा प्रस्तुत समस्या को हल नहीं कर रहा है । निश्चित रूप से, यदि आपको वह करने की आवश्यकता नहीं है जो ओपी करना चाहता है , तो आपको इसका उपयोग करना चाहिए। हालाँकि, यदि आप प्रत्येक परीक्षण फ़ाइल को कई describeब्लॉकों में लपेटना चाहते हैं, तो describeउस अवधि की फ़ाइलों को ब्लॉक करें, --recursiveऐसा नहीं करेंगे। यह देखकर कि यह ओपी की समस्या को हल नहीं करता है, मैं इसे "सर्वश्रेष्ठ" नहीं कहूंगा।
लुई

@louis - मेरा मानना ​​है कि आप प्रत्येक अलग फाइल को describeब्लॉकों में लपेट सकते हैं
इयान जैमिसन

4
@IanJamieson ओपी एक ही ब्लॉक द्वारा कई फाइलों को कवर करने की कोशिश कर रहा है । प्रश्न को देखो। "नियंत्रकों" ब्लॉक को और के परीक्षणों को शामिल करना चाहिए । मोचा आह्वान पर थप्पड़ मारना जादुई तरीके से ब्लॉक नहीं बनता । describedescribe./controllertests/messages.js./controllertests/users.js--recursivedescribe("Controllers"
लुई

3
@ लुईस बस मदद करने की कोशिश कर रहा है। क्षमा करें, यदि मैंने जादुई रूप से describeब्लॉक बनाने की कोशिश करके आपको नाराज कर दिया है - जो मैंने वास्तव में डंबलडोर से खुद करना सीखा था।
इयान जेमिसन

16

ऐसा कुछ भी नहीं है जो आपको कई परीक्षण फ़ाइलों को चलाने से रोकता है। आम तौर पर, प्रत्येक परीक्षण को दूसरे परीक्षण के परिणामों पर निर्भर नहीं होना चाहिए, इसलिए चर साझा करना कुछ ऐसा नहीं है जिसे आप करना चाहते हैं।

यहाँ एक उदाहरण है कि आप अपनी परीक्षण फ़ाइलों को कैसे व्यवस्थित कर सकते हैं।

.
├── app.js
└── test
    ├── common.js
    ├── mocha.opts
    │
    ├── controllers
    │   ├── messages-controller.js
    │   └── users-controller.js
    │
    └── models
        ├── messages-model.js
        └── users-model.js

फिर अपनी mocha.optsफ़ाइल के अंदर , सेट करना सुनिश्चित करें--recursive विकल्प ।

mocha.opts

--ui bdd
--recursive

वहाँ तो कर रहे हैं आम मॉड्यूल है कि आप सभी फ़ाइलों में शामिल करना चाहते हैं, आप के लिए है कि जोड़ सकते हैं common.jsफ़ाइल। की जड़ में फाइलेंtestनिर्देशिका नेस्टेड निर्देशिकाओं में फ़ाइलों से पहले चलेंगी।

common.js

global.chai = require('chai');
global.assert = chai.assert;
global.expect = chai.expect;
chai.should();
chai.config.includeStack = true;

process.env.NODE_ENV = 'test';

// Include common modules from your application that will be used among multiple test suites.
global.myModule = require('../app/myModule');

3
क्या कोई नियंत्रक और मॉडल निर्देशिकाओं में फ़ाइलों के लिए कोड जोड़ने का मन करेगा? इसका पूरा उदाहरण देना बहुत अच्छा होगा।
गाविन

@ गेविन - ये सिर्फ टेस्ट सूट होंगे इसलिए इनमें शामिल होंगेdescribe('mytest', function() { /* ..... etc */ });
इयान जैमिसन

8

मुझे पता है कि यह एक पुरानी पोस्ट है, लेकिन मैं ओपी द्वारा प्रस्तावित विधि के समान, मेरे लिए एक अच्छा समाधान है, जिसमें मैं झंकार करना चाहता था।

जिस प्रोजेक्ट पर मैं काम कर रहा हूं, उसका अच्छी तरह से परीक्षण किया गया है और परीक्षण बढ़ते रहे। मैंने उपयोग करना समाप्त कर दिया requireक्योंकि यह तुल्यकालिक है और इसलिए वास्तुकला में बहुत अधिक परिवर्तन के बिना अपने परीक्षणों की रचना करना थोड़ा आसान बनाता है:

// inside test/index.js

describe('V1 ROUTES', () => {
  require('./controllers/claims.test');
  require('./controllers/claimDocuments.test');
  require('./controllers/claimPhotos.test');
  require('./controllers/inspections.test');
  require('./controllers/inspectionPhotos.test');
  require('./controllers/versions.test');
  require('./services/login.v1.test');
});

describe('V2 ROUTES', () => {
  require('./services/login.v2.test');
  require('./services/dec-image.v2.test');
});

describe('V3 ROUTES', () => {
  require('./services/login.v3.test');
  require('./services/getInspectionPhotosv3.test');
  require('./services/getPolicyInfo.v3.test');
});

describe('ACTIONS', () => {
  require('./actions/notifications.test');
});

2

मुझे भी इसी तरह की समस्या थी, जहाँ मुझे एक ही श्रेणी में कक्षाओं के लिए परीक्षणों का गुच्छा था और मैं उन्हें एक आईडीडी आसान में देखने के लिए एक साथ समूह बनाना चाहता था। मेरे सभी परीक्षण और कोड पहले से ही ES6 मॉड्यूल का उपयोग कर रहे थे - मैं उन सभी को फिर से लिखना नहीं चाहता था requireजैसे कि मैंने अन्य उदाहरणों में देखा था।

मैंने इसे अपना "समूहीकरण" describeनिर्यात करके हल किया, और फिर इसे अपनी परीक्षण फ़ाइलों में आयात किया और प्रोग्रामेटिक रूप से उन्हें आयात में जोड़ा describe। मैंने पाइपलाइन के सभी को दूर करने के लिए एक सहायक विधि का निर्माण किया।

कुछ कैटेगरीज में .spec.js

const someCategory= describe("someCategory", () => {});


// Use this just like a regular `describe` to create a child of this scope in another file
export default function describeMember(skillName, testFn) {
  return describe(skillName, function configureContext() {
    // Make context a child of `someCategory` context
    function Context() {}
    Context.prototype = someCategory.ctx;
    this.ctx = new Context();
    // Re-parent the suite created by `describe` above (defaults to root scope of file it was created in)
    this.parent.suites.pop();
    someCategory.addSuite(this);
    // Invoke the fn now that we've properly set up the parent/context
    testFn.call(this);
  });
}

व्यक्तिगत परीक्षणों में:

import { default as describeCategoryMember } from './someCategory.spec';

describeCategoryMember('something', () => {
    describe('somethingElse', () => {
        ...
    });

    it('a test', () => {
        ...
    });
})

-11
describe( 'Running automation test, Please wait for all test to complete!'.red, function () {


    var run = require( './Test.js' );

    for ( var i = 0; i < 2; i++ ) {
        run.badLogin();
        run.loginLimited();
        run.acceptJob();
        run.drivingToJob();
        run.arrivedAtJob();
        run.towingJob();
        run.arrivedDestination();
        run.jobComplete();
        run.restrictionLicensePlate();
        run.newNodeMainMenu();
        run.newNodeMainMenuToDrafts();
        run.draftDelete();
        run.resetAllData();
        run.companyVehicle();
        run.actionsScreenClockInOut();
        run.mainMenuLogout();
        run.loginAdmin();
        run.actionsScreenLogout();
    }
} );

3
कोड के साथ विवरण जोड़ना सबसे अच्छा है ताकि अन्य यह निर्धारित कर सकें कि क्या यह स्वीकार्य उत्तर है।
Suever

2
क्यों लूप? में क्या है ./Test.js? कौन जाने? रिकॉर्ड के लिए, मैं वर्तमान में मोचा टैग में शीर्ष उत्तरदाता हूं । मुझे पता है कि मोचा अंदर और बाहर है लेकिन मैं इस जवाब का कोई मतलब नहीं निकाल सकता।
लुइस

@ लुइस को लगता है कि वह लूप का उपयोग करके n बार परीक्षण चलाना चाहते थे ।
आकाश अग्रवाल
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.