Elixir ट्रैक पर टेस्टिंग

Exercism पर अपने Elixir अभ्यासों को टेस्ट करना सीखिए।


टर्मिनल से अभ्यास की मूल डायरेक्टरी में जाइए, फिर टेस्ट इनसे चलाइए:

$ mix test

यह test सबफोल्डर में मौजूद टेस्ट फाइल चलाएगा, यानी ऐसी फाइल जिसका नाम _test.exs पर खत्म होता है।

पेंडिंग टेस्ट

प्रैक्टिस अभ्यासों के टेस्ट सूट में पहले टेस्ट के अलावा बाकी सभी टेस्ट स्किप करने के लिए टैग किए गए हैं।

जब कोई टेस्ट पास हो जाए, तो अगला टेस्ट भी चलाने के लिए उससे जुड़े @tag :pending को # चिह्न से कमेंट कर दीजिए।

उदाहरण के लिए:

# @tag :pending
test "shouting" do
  assert Bob.hey("WATCH OUT!") == "Whoa, chill out!"
end

अगर आप सारे टेस्ट एक साथ चलाना चाहते हैं, तो mix test कमांड पर --include फ्लैग लगाकर सभी स्किप किए गए टेस्ट शामिल कर सकते हैं:

$ mix test --include pending

या फिर टेस्ट सूट में ExUnit.configure लाइन को कमेंट करके सारे टेस्ट चालू कर सकते हैं।

# ExUnit.configure exclude: :pending, trace: true

Elixir में टेस्टिंग की कुछ और सुविधाएँ

ExUnit और mix test टेस्ट को समूहों में बाँटने, टैग करने और चलाने के कई तरीके देते हैं, और टेस्ट कैसे चलें यह नियंत्रित करने के भी कई तरीके। इनमें से बहुत कुछ नीचे संक्षेप में दिया गया है।

कुछ खास टेस्ट चलाने के तरीके

डॉक्युमेंटेशन:

किसी एक फाइल के टेस्ट चलाना

किसी एक फाइल के सारे टेस्ट mix test से चलाए जा सकते हैं, बस फाइल का नाम दे दीजिए:

$ mix test test/<FILE>.exs

ध्यान दें: इस तरीके से असल में कौन-से टेस्ट चलेंगे, यह tagging पर निर्भर कर सकता है।

अलग-अलग टेस्ट चलाना

किसी एक टेस्ट को फाइल में उसका लाइन नंबर देकर चलाया जा सकता है:

$ mix test test/<FILE>.exs:LINENUM

कई लाइन संख्याओं को : से अलग करके देने पर कई टेस्ट चलाए जा सकते हैं।

उदाहरण के लिए, मान लीजिए एक फाइल है जिसकी सामग्री नीचे दी गई है, साथ में लाइन संख्याएँ भी:

test "Test 1" do           # 1
  # test implementation    # 2-6
end                        # 7
                           # 8
test "Test 2" do           # 9
  # test implementation    # 10-21
end                        # 22
                           # 23
test "Test 3" do           # 24
  # test implementation    # 25-35
end                        # 36

पहला और तीसरा टेस्ट ऐसे चलाए जा सकते हैं:

$ mix test test/FILE.exs:1:24

ध्यान दें: लाइन संख्याओं से टेस्ट चुनते समय tagging को नज़रअंदाज़ किया जाता है।

टेस्ट के समूह चलाना

describe की मदद से टेस्ट को समूहों में बाँटा जा सकता है:

describe "short test group description" do
  test "test description" do
    # test implementation
  end

  test "another test description" do
    # test implementation
  end
end

किसी समूह के सारे टेस्ट फाइल में उसका लाइन नंबर देकर चलाए जा सकते हैं, ठीक वैसे ही जैसे अलग-अलग टेस्ट के लिए लाइन नंबर देते हैं।

डॉक्युमेंटेशन:

mix test के कुछ और काम के विकल्प

  • --include और --exclude - इनके @tag के आधार पर तय होता है कि कौन-से टेस्ट चलेंगे और कौन-से नहीं
  • --failed - सिर्फ वे टेस्ट चलाता है जो पिछली बार चलाने पर फेल हुए थे
  • --max-failures - इतने टेस्ट फेल होते ही सूट और टेस्ट चलाना बंद कर देता है
  • --seed - टेस्ट का क्रम बेतरतीब करने वाले रैंडम नंबर जनरेटर को सीड देता है। --seed 0 रैंडमाइज़ेशन बंद कर देता है, इसलिए एक फाइल के टेस्ट हमेशा उसी क्रम में चलेंगे जिस क्रम में उन्हें लिखा गया था
  • --stale - सिर्फ वे टेस्ट चलाता है जो ऐसे मॉड्यूल का इस्तेमाल करते हैं जो पिछली बार --stale के साथ टेस्ट चलने के बाद बदल गए हैं
  • --only task_id:1 - या किसी और नंबर के साथ; लर्निंग अभ्यासों में यह सिर्फ उसी टास्क से जुड़े टेस्ट चलाता है

डॉक्युमेंटेशन:

टाइपस्पेक्स और Dialyzer (ERlang प्रोग्राम के लिए DIscrepancy AnalYZer)

Elixir के अभ्यासों में lib सबडायरेक्टरी में एक ढाँचा इम्प्लीमेंटेशन फाइल होती है। यह फाइल उस मॉड्यूल और फंक्शनों की रूपरेखा देती है जिन्हें आपको लागू करना है। ज़्यादातर अभ्यासों में फंक्शन की घोषणा के ऊपर टाइपस्पेक्स मिलेंगे। ये @spec टैग से शुरू होते हैं और आमतौर पर @spec function_name(type1, type2) :: return_type प्रारूप में होते हैं। Elixir और Erlang में इनका इस्तेमाल डॉक्युमेंटेशन के तौर पर होता है, और Dialyzer नाम के टूल के साथ मिलकर ये टाइप की असंगतियाँ और संभावित बग ढूँढने में मदद करते हैं। ज़्यादा जानकारी के लिए टाइपस्पेक्स का डॉक्युमेंटेशन देखिए। Dialyzer के डॉक्युमेंटेशन के लिए Erlang -- dialyzer देखिए।

वैकल्पिक रूप से, आप अपनी इम्प्लीमेंटेशन के टाइप Dialyzer से जाँच सकते हैं। इसके लिए आपको कुछ कदम उठाने होंगे। ऐसा करने के लिए आपको अपने अभ्यास की mix.exs फाइल में Dialyxir डिपेंडेंसी जोड़नी होगी।

defp deps do
  # Add this:
  [{:dialyxir, "~> 0.4", only: [:dev]}]
end

इसके बाद कमांड लाइन से डिपेंडेंसी लाने और उन्हें कंपाइल करने के लिए mix टास्क चलाइए:

$ mix deps.get
...
$ mix deps.compile
...

अगर आप पहली बार Dialyzer चला रहे हैं, तो बहुत संभव है कि आपके पास plt फाइल न हो। पर्सिस्टेंट लुकअप टेबल, यानी PLT, Dialyzer इसे Elixir और Erlang के बिल्ट-इन टाइप की जानकारी कैश करने के लिए इस्तेमाल करता है। उचित डिफोल्ट के साथ plt बनाने के लिए यह चलाइए:

$ mix dialyzer --plt

अंत में इसे ऐसे चलाया जा सकता है:

$ mix dialyzer

ध्यान रखिए कि पाथ को अपने सिस्टम में Elixir लाइब्रेरी के पाथ के मुताबिक बदल लें। उदाहरण के लिए, अगर आपने Elixir homebrew से इंस्टॉल किया है, तो यह शायद आपको /usr/local/Cellar/elixir/1.3.2 के नीचे मिलेगा।

यह दोहराना ज़रूरी है कि अभ्यास पूरा करते समय Dialyzer चलाना और सारी चेतावनियाँ हटाना वैकल्पिक कदम है। Dialyzer की चेतावनियाँ समझना मुश्किल हो सकता है। उदाहरण के लिए, Bob अभ्यास की इस बेहद बेतुकी इम्प्लीमेंटेशन की चेतावनियाँ देखिए।

defmodule Bob do
  @spec hey(input :: String.t()) :: String.t()
  def hey(input) do
    1
  end

  def hey(input) do
  end
end

इससे ये चेतावनियाँ मिलती हैं।

bob.exs:2: Invalid type specification for function 'Elixir.Bob':hey/1. The success typing is (_) -> 1
bob.exs:7: The variable _input@1 can never match since previous clauses completely covered the type any()

पहली चेतावनी का मतलब है कि फंक्शन सही टाइप नहीं लौटा रहा। अंतिम चेतावनी बताती है कि दूसरी फंक्शन परिभाषा तक कभी पहुँचना संभव नहीं, क्योंकि पहली फंक्शन परिभाषा हमेशा मैच कर जाती है।