আমি কীভাবে পরীক্ষার প্যাকেজটি ব্যবহার করে পরীক্ষার সেটআপ করতে পারি


111

আমি কীভাবে সামগ্রিক পরীক্ষার সেটআপ প্রসেসিং করতে পারি যা পরীক্ষার প্যাকেজটি ব্যবহার করার সময় সমস্ত পরীক্ষার মঞ্চ নির্ধারণ করে ?

নুনিতে উদাহরণ হিসাবে একটি [SetUp]বৈশিষ্ট্য রয়েছে।

[TestFixture]
public class SuccessTests
{
  [SetUp] public void Init()
  { /* Load test data */ }
}

উত্তর:


159

Go 1.4 দিয়ে শুরু করে আপনি সেটআপ / টিয়ারডাউন প্রয়োগ করতে পারেন (প্রতিটি পরীক্ষার আগে / পরে আপনার ফাংশনগুলি অনুলিপি করার প্রয়োজন নেই)। ডকুমেন্টেশন রূপরেখা করা হয় এখানে মধ্যে প্রধান অধ্যায়:

টেস্টমেইন মূল গোরোটিনে চলে এবং মিঃ রুনের কল করার জন্য সেটআপ এবং টিয়ারডাউন যা প্রয়োজন তা করতে পারে। এরপরে m.Run এর ফলাফলের সাথে os.Exit কল করা উচিত

এটি নির্ধারণ করতে আমার কিছুটা সময় লেগেছে যে এর অর্থ এই যে কোনও পরীক্ষায় যদি কোনও func TestMain(m *testing.M)ফাংশন থাকে তবে পরীক্ষাটি চালানোর পরিবর্তে এই ফাংশনটি কল করা হবে। এবং এই ফাংশনে আমি সংজ্ঞা দিতে পারি যে পরীক্ষাগুলি কীভাবে চলবে। উদাহরণস্বরূপ, আমি গ্লোবাল সেটআপ এবং টিয়ারডাউন প্রয়োগ করতে পারি:

func TestMain(m *testing.M) {
    setup()
    code := m.Run() 
    shutdown()
    os.Exit(code)
}

অন্যান্য কয়েকটি উদাহরণ এখানে পাওয়া যাবে

সর্বশেষ প্রকাশে গো পরীক্ষার কাঠামোর সাথে যুক্ত টেস্টমাইন বৈশিষ্ট্যটি বেশ কয়েকটি পরীক্ষামূলক ব্যবহারের ক্ষেত্রে সহজ সমাধান। টেস্টমেইন সেটআপ এবং শাটডাউন সম্পাদন, পরীক্ষার পরিবেশ নিয়ন্ত্রণ করতে, শিশু প্রক্রিয়াতে বিভিন্ন কোড চালাতে বা পরীক্ষার কোড দ্বারা ফাঁস হওয়া সংস্থানগুলি পরীক্ষা করার জন্য একটি বিশ্বব্যাপী হুক সরবরাহ করে। বেশিরভাগ প্যাকেজগুলির জন্য টেস্টমেনের প্রয়োজন হবে না, তবে এটি যখন প্রয়োজন হয় তখন এটি স্বাগত সংযোজন।


17
TestMainএকবার প্যাকেজে থাকে তাই এটি তেমন কার্যকর হয় না। আমি দেখতে পেলাম যে আরও জটিল উদ্দেশ্যে সাবসেটগুলি আরও ভাল।
Inanc Gumus

3
গ্লোবাল ভেরিয়েবল ব্যবহার না করে আপনি কীভাবে সেটআপ ফাংশন থেকে পরীক্ষায় প্রসঙ্গটি পাস করবেন? উদাহরণস্বরূপ, যদি মাইসেটআপফানশন () (একটি অনন্য, এলোমেলো নাম সহ) পরীক্ষা করার জন্য একটি অস্থায়ী ডিরেক্টরি তৈরি করে, পরীক্ষাগুলি ডিরেক্টরিটির নামটি কীভাবে জানতে পারে? এই প্রসঙ্গটি নির্ধারণের জন্য অবশ্যই একটি জায়গা থাকতে হবে ??
Lqueryvg

1
দেখে মনে হচ্ছে পরীক্ষার জন্য হুকের আগে ও পরে এটি পরিচালনা করার আনুষ্ঠানিক উপায়, golang.org/pkg/testing/#hdr- অফিসিয়াল ডকুমেন্টেশনের জন্য মেইন
ডি-জ্যাকআপ

4
@ আইয়ানকগামাসlstat $GOROOT/subtests: no such file or directory
030

1
দয়া করে মনে রাখবেন যে 'কোড: = মি। রুন ()' এমনটি যা অন্য টেস্টফিউশনগুলি চালায়!
অ্যালেক্স পুনেন

49

ফাইলটিতে একটি init()ফাংশন রেখে এটি অর্জন করা যায় _test.go। এটি init()ফাংশনের আগে চালানো হবে ।

// package_test.go
package main

func init() {
     /* load test data */
}

_Test.init () প্যাকেজ init () ফাংশনের আগে ডাকা হবে।


2
আমি জানি আপনি নিজের প্রশ্নের উত্তর দিচ্ছেন তাই এটি সম্ভবত আপনার নিজের ব্যবহারের ক্ষেত্রে সন্তুষ্ট তবে এটি আপনার প্রশ্নের সাথে যুক্ত নুনিট উদাহরণের সমতুল্য নয়।
জেমস হেনস্ট্রিজ

ভাল @ জেমস, আমি ইস্যুটির উত্তর দেওয়ার পথে একটি চিন্তাভাবনা দেখিয়েছি এবং অন্যরা ইতিমধ্যে আপনার সহ কিছু ভাল অন্তর্দৃষ্টি সরবরাহ করেছে। টিউনগুলির কাছে যাওয়ার জন্য বাইরের প্রভাবগুলি পেতে এটি দরকারী। ধন্যবাদ।
মিল্টনব

2
যথেষ্ট ফর্সা। আপনি এই উত্তরে যা দেখিয়েছেন তা [TestFixtureSetUp]পরিবর্তে NUnit এর বৈশিষ্ট্যটি ব্যবহার করার কাছাকাছি ।
জেমস হেনস্ট্রিজ

2
এতে ছেঁড়া অংশটি অন্তর্ভুক্ত নয়
তারাস ম্যাটস্ক

7
যদি আপনার পরীক্ষার ফাইলটি মূল ফাংশন সহ একই প্যাকেজে থাকে তবে এটি কোনও ভাল সমাধান নয়।
মাউস ওয়ান্টেড

28

ইউনিট পরীক্ষায় একটি সাধারণ ফাংশন দেওয়া:

package math

func Sum(a, b int) int {
    return a + b
}

আপনি এটি সেটআপ ফাংশন দিয়ে পরীক্ষা করতে পারেন যা টিয়ারডাউন ফাংশনটি ফিরিয়ে দেয়। এবং সেটআপ কল করার পরে () আপনি টিয়ারডাউন () এ একটি বিলম্বিত কল করতে পারেন।

package math

import "testing"

func setupTestCase(t *testing.T) func(t *testing.T) {
    t.Log("setup test case")
    return func(t *testing.T) {
        t.Log("teardown test case")
    }
}

func setupSubTest(t *testing.T) func(t *testing.T) {
    t.Log("setup sub test")
    return func(t *testing.T) {
        t.Log("teardown sub test")
    }
}

func TestAddition(t *testing.T) {
    cases := []struct {
        name     string
        a        int
        b        int
        expected int
    }{
        {"add", 2, 2, 4},
        {"minus", 0, -2, -2},
        {"zero", 0, 0, 0},
    }

    teardownTestCase := setupTestCase(t)
    defer teardownTestCase(t)

    for _, tc := range cases {
        t.Run(tc.name, func(t *testing.T) {
            teardownSubTest := setupSubTest(t)
            defer teardownSubTest(t)

            result := Sum(tc.a, tc.b)
            if result != tc.expected {
                t.Fatalf("expected sum %v, but got %v", tc.expected, result)
            }
        })
    }
}

গো পরীক্ষার সরঞ্জামটি শেল কনসোলে লগিং স্টেটমেন্টগুলি রিপোর্ট করবে:

% go test -v
=== RUN   TestAddition
=== RUN   TestAddition/add
=== RUN   TestAddition/minus
=== RUN   TestAddition/zero
--- PASS: TestAddition (0.00s)
    math_test.go:6: setup test case
    --- PASS: TestAddition/add (0.00s)
        math_test.go:13: setup sub test
        math_test.go:15: teardown sub test
    --- PASS: TestAddition/minus (0.00s)
        math_test.go:13: setup sub test
        math_test.go:15: teardown sub test
    --- PASS: TestAddition/zero (0.00s)
        math_test.go:13: setup sub test
        math_test.go:15: teardown sub test
    math_test.go:8: teardown test case
PASS
ok      github.com/kare/go-unit-test-setup-teardown 0.010s
% 

আপনি এই পদ্ধতির সাথে সেটআপ / টিয়ারডাউন করার জন্য কিছু অতিরিক্ত পরামিতিগুলি পাস করতে পারেন।


2
এখন এটি একটি আসল সহজ তবে কার্যকর কৌশল। গো সিনট্যাক্সের দুর্দান্ত ব্যবহার।
মিল্টনব

1
হ্যাঁ, তবে এটি নেস্টনেস বাড়িয়ে তোলে ( জাভাস্ক্রিপ্টে এক ধরণের পিরামিড অফ ডুম )। এবং, টেস্টগুলি বাইরের পরীক্ষার মতো স্যুট দ্বারা স্বয়ংক্রিয়ভাবে চালিত হয় না।
ইনঙ্ক গুমাস

12

সাধারণত, যাওয়ার সময় পরীক্ষা অন্যান্য ভাষার মতো একই স্টাইলে লেখা হয় না। প্রায়শই, পরীক্ষামূলকভাবে অপেক্ষাকৃত কম কাজ হয় তবে প্রতিটি পরীক্ষার ক্ষেত্রে একটি টেবিল-চালিত সেট থাকে। গো দলের একজনের লেখা এই নিবন্ধটি দেখুন

টেবিল-চালিত পরীক্ষার মাধ্যমে আপনি কেবলমাত্র কোনও সেটআপ কোড লুপের আগে রেখেছিলেন যা টেবিলে বর্ণিত পৃথক টেস্ট-কেসগুলি কার্যকর করে এবং পরে কোনও ক্লিনআপ কোড রাখে।

আপনি যদি এখনও টেস্ট ফাংশনগুলির মধ্যে সেটআপ কোডটি ভাগ করে নিয়ে থাকেন তবে আপনি ভাগ করে নেওয়া সেটআপ কোডটিকে একটি ফাংশন থেকে বের করতে পারেন এবং এটি ব্যবহার করা sync.Onceগুরুত্বপূর্ণ যদি এটি ঠিক একবার কার্যকর করা হয় (বা অন্য উত্তর হিসাবে বোঝায়, ব্যবহার করুন init()তবে এটির সেটআপটি অসুবিধে রয়েছে পরীক্ষার মামলাগুলি পরিচালনা না করা হলেও সম্পন্ন করা হবে (সম্ভবত আপনি পরীক্ষার কেসগুলি ব্যবহার করে সীমাবদ্ধ করে রেখেছেন because go test -run <regexp>)

আমি যদি বলি যে আপনি যদি মনে করেন যে আপনার যদি বিভিন্ন টেস্টের মধ্যে ভাগ করে নেওয়ার দরকার হয় যা ঠিক একবার সম্পাদিত হয় তবে আপনার যদি সত্যিই এটির প্রয়োজন হয় এমন চিন্তাভাবনা করা উচিত, এবং যদি কোনও টেবিল-চালিত পরীক্ষাটি আরও ভাল না হয়।


6
ফ্ল্যাগ পার্সার, বা সংখ্যার উপর মন্থনকারী একটি অ্যালগরিদম জাতীয় তুচ্ছ জিনিস পরীক্ষা করার সময় এটি দুর্দান্ত। তবে কার্যকারিতার বিভিন্ন অংশের পরীক্ষা করার চেষ্টা করার সময় এটি সত্যিই সহায়তা করে না যেগুলির জন্য একই রকমের বয়লারপ্লিট কোডের প্রয়োজন require আমি মনে করি যে আমি আমার পরীক্ষার ক্রিয়াগুলি একটি অ্যারেতে সংজ্ঞায়িত করতে পারি এবং সেগুলির উপরে পুনরাবৃত্তি করতে পারি, তবে তারপরে এটি কোনও সাধারণ লুপের মতো এতটা টেবিল চালিত নয় যা সত্যই কেবল টেস্টিং ফ্রেমওয়ার্কের মধ্যেই তৈরি করা উচিত (একটি সঠিক পরীক্ষার স্যুট আকারে) সেটআপ / টিয়ারডাউন ফাংশন সহ)
iamtheddrman

9

গো পরীক্ষার কাঠামোটিতে NUnit এর সেটআপ অ্যাট্রিবিউট (স্যুটে প্রতিটি পরীক্ষার আগে ডাকা একটি ফাংশন চিহ্নিতকরণ) এর সমান কিছু নেই । যদিও কয়েকটি বিকল্প রয়েছে:

  1. SetUpযেখানে প্রয়োজন সেখানে প্রতিটি পরীক্ষা থেকে কেবল আপনার ফাংশনটি কল করুন ।

  2. গো'র পরীক্ষামূলক কাঠামোতে এক্সটেনশন ব্যবহার করুন যা xUnit দৃষ্টান্ত এবং ধারণাগুলি প্রয়োগ করে। তিনটি শক্তিশালী বিকল্প মাথায় আসে:

এই লাইব্রেরির প্রত্যেকটি আপনাকে এক্স xnnit ফ্রেমওয়ার্কের মতো স্যুট / ফিক্সচারগুলিতে আপনার পরীক্ষাগুলি সংগঠিত করতে উত্সাহিত করে এবং প্রতিটি Test*পদ্ধতির আগে স্যুট / ফিক্সারের ধরণের সেটআপ পদ্ধতিগুলিকে কল করবে ।


0

নির্লজ্জ প্লাগ, আমি এই সমস্যাটি ঠিকভাবে সমাধান করতে সহায়তা করার জন্য https://github.com/houqp/gtest তৈরি করেছি ।

এখানে একটি দ্রুত উদাহরণ:

import (
  "strings"
  "testing"
  "github.com/houqp/gtest"
)

type SampleTests struct{}

// Setup and Teardown are invoked per test group run
func (s *SampleTests) Setup(t *testing.T)      {}
func (s *SampleTests) Teardown(t *testing.T)   {}
// BeforeEach and AfterEach are invoked per test run
func (s *SampleTests) BeforeEach(t *testing.T) {}
func (s *SampleTests) AfterEach(t *testing.T)  {}

func (s *SampleTests) SubTestCompare(t *testing.T) {
  if 1 != 1 {
    t.FailNow()
  }
}

func (s *SampleTests) SubTestCheckPrefix(t *testing.T) {
  if !strings.HasPrefix("abc", "ab") {
    t.FailNow()
  }
}

func TestSampleTests(t *testing.T) {
  gtest.RunSubTests(t, &SampleTests{})
}

আপনি প্রতিটি প্যাকেজের মধ্যে সেটআপ / টিয়ারডাউন রুটিনের বিভিন্ন সেট ব্যবহার করে যে কোনও পরীক্ষার গোষ্ঠী হিসাবে তৈরি করতে পারেন।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.