प्रौद्योगिकी साझेदारी

गो-ज्ञानपरीक्षा-उदाहरणपरीक्षा

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

प्रथमं पठितुं अनुशंसितम् अस्ति : https://blog.csdn.net/a18792721831/article/details/140062769

गो-ज्ञान परीक्षण-कार्य तन्त्र

1. परिभाषा

नमूनापरीक्षा अवश्यमेव सुनिश्चितं करोति यत् परीक्षणसञ्चिका सह समाप्तं भवति_test.goअंत।
परीक्षणविधिः भवितुमर्हतिExampleXxxआरंभ।
परीक्षणसञ्चिकाः स्रोतसङ्केतस्य समाने निर्देशिकायां वा पृथक् निर्देशिकायां वा भवितुम् अर्हन्ति ।
एकपङ्क्तिनिर्गमस्वरूपं // Output: <expected string> इति रूपेण ज्ञापयन्तु
बहुपङ्क्तिनिर्गमस्य अन्वेषणस्वरूपं // आउटपुट् अस्ति: n <expected string> n <expected string> n, प्रत्येकं अपेक्षितं स्ट्रिंग् एकां रेखां गृह्णाति
अक्रमितनिर्गमस्य अन्वेषणस्य प्रारूपं // अक्रमितनिर्गमः अस्ति: n <expected string> n <expected string> n <expected string>, प्रत्येकं अपेक्षितं स्ट्रिंग् एकां रेखां व्याप्नोति
परीक्षणमाला स्वयमेव स्ट्रिंग् इत्यस्मात् पूर्वं पश्चात् च श्वेतस्थानवर्णान् अवहेलयिष्यति ।
यदि परीक्षणकार्य्ये Output प्रतिनिधित्वं नास्ति तर्हि परीक्षणकार्यं न निष्पादितं भविष्यति ।

2. उदाहरणम्

स्ट्रिंग् आउटपुट् मध्ये एकपङ्क्तिः, बहुपङ्क्तयः, क्रमात् बहिः वा भवेत् ।
कार्यं यथा- १.

func Hello() {
	fmt.Println("Hello")
}

func HelloTwo() {
	fmt.Println("Hello")
	fmt.Println("hi")
}

func HelloMore() {
	m := make(map[string]string)
	m["hello"] = "Hello"
	m["hi"] = "hi"
	m["你好"] = "你好"
	for _, v := range m {
		fmt.Println(v)
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

ततः उदाहरणपरीक्षायाः उपयोगं कुर्वन्तु

func ExampleHello() {
	Hello()
	// Output: Hello
}

func ExampleHelloTwo() {
	HelloTwo()
	// Output:
	// Hello
	// hi
}

func ExampleHelloMore() {
	HelloMore()
	// Unordered output:
	// Hello
	// hi
	// 你好
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

उपयुञ्जताम्‌go test -v नमूनापरीक्षाः निष्पादयन्तु, -v कन्सोल् आउटपुट् परिणामान् सूचयति
अत्र चित्रविवरणं सम्मिलितं कुर्वन्तु

3. दत्तांशसंरचना

प्रत्येकं परीक्षणं संकलनस्य अनन्तरं वहितुं दत्तांशसंरचना भवति उदाहरणपरीक्षायाः कृते, एतत् InternalExample अस्ति ।

type InternalExample struct {
	Name      string // 测试名称
	F         func() // 测试函数
	Output    string // 期望字符串
	Unordered bool // 输出是否无序
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

यथा - निम्नलिखितप्रसङ्गः - १.

func ExampleHelloMore() {
	HelloMore()
	// Unordered output:
	// Hello
	// hi
	// 你好
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

संकलनस्य अनन्तरं दत्तांशसंरचनायाः सदस्याः

InternalExample.Name = "ExampleHelloMore"
InternalExample.F = ExampleHelloMore()
InternalExample.Output = "hellonhin你好n"
InternalExample.Unordered = true
  • 1
  • 2
  • 3
  • 4

4. संकलनप्रक्रिया

लेखे : १. गो-ज्ञान परीक्षण-कार्य तन्त्र

गो-ज्ञान परीक्षण-कार्य तन्त्र

, वयं जानीमः यत् संकलनकाले तस्य आह्वानं भविष्यतिsrc/cmd/go/internal/load/test.go:528
अत्र चित्रविवरणं सम्मिलितं कुर्वन्तु

भारस्य मध्ये चतुर्विधपरीक्षाः पृथक् पृथक् संसाधिताः भविष्यन्ति : इकाईपरीक्षा, कार्यप्रदर्शनपरीक्षा, मुख्यपरीक्षा, नमूनापरीक्षा च ।
अत्र चित्रविवरणं सम्मिलितं कुर्वन्तु

परीक्षणसञ्चिकां संसाधयन् टिप्पण्यां आउटपुट् अस्ति वा इति पश्यन्तु
अत्र चित्रविवरणं सम्मिलितं कुर्वन्तु

तथा मेटाडाटां समाहितं कुर्वन्तु
अत्र चित्रविवरणं सम्मिलितं कुर्वन्तु

मेटाडाटा एन्कैप्सुलेट् कृत्वा, मेटाडाटा इत्यस्य उपयोगः टेम्पलेट् रेण्डर् कर्तुं, Main प्रविष्टिं जनयितुं, एकस्मिन् समये InternalExample स्लाइस् रेण्डर् कर्तुं च भविष्यति ।
अत्र चित्रविवरणं सम्मिलितं कुर्वन्तु

5. निष्पादनप्रक्रिया

यदा निष्पादितं तदा निष्पादितं भविष्यतिtesting.M.Run, Run इत्यस्मिन् निष्पादितं भविष्यतिrunExamples
अत्र चित्रविवरणं सम्मिलितं कुर्वन्तु

func runExamples(matchString func(pat, str string) (bool, error), examples []InternalExample) (ran, ok bool) {
	ok = true
	var eg InternalExample
	// 对每个实例测试进行执行
	for _, eg = range examples {
	    // 是否匹配
		matched, err := matchString(*match, eg.Name)
		if err != nil {
			fmt.Fprintf(os.Stderr, "testing: invalid regexp for -test.run: %sn", err)
			os.Exit(1)
		}
		if !matched {
			continue
		}
		ran = true
		// 执行
		if !runExample(eg) {
			ok = false
		}
	}
	return ran, ok
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
func runExample(eg InternalExample) (ok bool) {
    // 附加输出
	if *chatty {
		fmt.Printf("=== RUN   %sn", eg.Name)
	}
	// 获取标准输出
	stdout := os.Stdout
	// 新建管道,将标准输出拷贝一份
	r, w, err := os.Pipe()
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
	os.Stdout = w
	// 创建一个管道,用于接收标准输出返回的字符串
	outC := make(chan string)
	// 在一个单独的 goroutine 中处理拷贝的输出
	go func() {
		var buf strings.Builder
		_, err := io.Copy(&buf, r)
		r.Close()
		if err != nil {
			fmt.Fprintf(os.Stderr, "testing: copying pipe: %vn", err)
			os.Exit(1)
		}
		outC <- buf.String()
	}()
	finished := false
	start := time.Now()
	// 在延迟函数中,读取管道中的数据
	defer func() {
		timeSpent := time.Since(start)
		w.Close()
		os.Stdout = stdout
		// 获取标准输出
		out := <-outC
		err := recover()
		// 调用 processRunResult 进行比较 
		ok = eg.processRunResult(out, timeSpent, finished, err)
	}()
	// 执行示例函数,也就是目标函数
	eg.F()
	finished = true
	return
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
func (eg *InternalExample) processRunResult(stdout string, timeSpent time.Duration, finished bool, recovered interface{}) (passed bool) {
	passed = true
	dstr := fmtDuration(timeSpent)
	var fail string
	// 标准输出,去除空字符,这也是为何实例测试中会忽略空白字符
	got := strings.TrimSpace(stdout)
	// 期望输出
	want := strings.TrimSpace(eg.Output)
	// 是否乱序
	if eg.Unordered {
	    // 先排序,然后字符串比较
		if sortLines(got) != sortLines(want) && recovered == nil {
			fail = fmt.Sprintf("got:n%snwant (unordered):n%sn", stdout, eg.Output)
		}
	} else {
		if got != want && recovered == nil {
			fail = fmt.Sprintf("got:n%snwant:n%sn", got, want)
		}
	}
	if fail != "" || !finished || recovered != nil {
		fmt.Printf("--- FAIL: %s (%s)n%s", eg.Name, dstr, fail)
		passed = false
	} else if *chatty {
		fmt.Printf("--- PASS: %s (%s)n", eg.Name, dstr)
	}
	if recovered != nil {
		// Propagate the previously recovered result, by panicking.
		panic(recovered)
	}
	if !finished && recovered == nil {
		panic(errNilPanicOrGoexit)
	}
	return
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34