網(wǎng)站首頁(yè) 編程語(yǔ)言 正文
1.測(cè)試?yán)臃治?/h2>
example_test.go,展示了With-系列的4個(gè)例子
func ExampleWithCancel() { ? gen := func(ctx context.Context) <-chan int { ? ? dst := make(chan int) ? ? n := 1 ? ? go func() { ? ? ? for { ? ? ? ? select { ? ? ? ? case <-ctx.Done(): ? ? ? ? ? return // returning not to leak the goroutine ? ? ? ? case dst <- n: ? ? ? ? ? n++ ? ? ? ? } ? ? ? } ? ? }() ? ? return dst ? } ? ctx, cancel := context.WithCancel(context.Background()) ? defer cancel() // cancel when we are finished consuming integers ? for n := range gen(ctx) { ? ? fmt.Println(n) ? ? if n == 5 { ? ? ? break ? ? } ? } ? // Output: ? // 1 ? // 2 ? // 3 ? // 4 ? // 5 }
結(jié)構(gòu)分析,gen
是一個(gè)函數(shù),返回值是一個(gè)信道, for range channel
是有特殊意義的, for會(huì)循環(huán)從channel讀數(shù)據(jù),直到channel被close(),不然就是無(wú)限循環(huán).
gen內(nèi)部的協(xié)程就是典型的閉包,for range會(huì)不斷觸發(fā)讀,gen內(nèi)部的for select 會(huì)不斷觸發(fā)寫,主協(xié)程讀5次之后,會(huì)結(jié)束main函數(shù),會(huì)觸發(fā)defer函數(shù), 也就是取消操作對(duì)應(yīng)的回調(diào),此時(shí)done信道會(huì)被close,gen內(nèi)部的協(xié)程會(huì)正常退出.
這個(gè)例子是測(cè)試支持取消信號(hào)的上下文,取消函數(shù)的調(diào)用放在了main
的defer
函數(shù)中.
const shortDuration = 1 * time.Millisecond func ExampleWithDeadline() { ? d := time.Now().Add(shortDuration) ? ctx, cancel := context.WithDeadline(context.Background(), d) ? // Even though ctx will be expired, it is good practice to call its ? // cancellation function in any case. Failure to do so may keep the ? // context and its parent alive longer than necessary. ? defer cancel() ? select { ? case <-time.After(1 * time.Second): ? ? fmt.Println("overslept") ? case <-ctx.Done(): ? ? fmt.Println(ctx.Err()) ? } ? // Output: ? // context deadline exceeded }
deadline
的這個(gè)例子,在main
的defer
中也有主動(dòng)調(diào)用取消函數(shù)的. 實(shí)際上通過(guò)打印可以顯示deadline是否按預(yù)期工作.
func ExampleWithTimeout() { ? ctx, cancel := context.WithTimeout(context.Background(), shortDuration) ? defer cancel() ? select { ? case <-time.After(1 * time.Second): ? ? fmt.Println("overslept") ? case <-ctx.Done(): ? ? fmt.Println(ctx.Err()) // prints "context deadline exceeded" ? } ? // Output: ? // context deadline exceeded }
timeout
只是deadline
的一種簡(jiǎn)寫.
func ExampleWithValue() { ? type favContextKey string ? f := func(ctx context.Context, k favContextKey) { ? ? if v := ctx.Value(k); v != nil { ? ? ? fmt.Println("found value:", v) ? ? ? return ? ? } ? ? fmt.Println("key not found:", k) ? } ? k := favContextKey("language") ? ctx := context.WithValue(context.Background(), k, "Go") ? f(ctx, k) ? f(ctx, favContextKey("color")) ? // Output: ? // found value: Go ? // key not found: color }
context.WithValue
和Context.Value()
是存取操作, 取的時(shí)候,如果key沒(méi)找到,會(huì)返回nil.
2.單元測(cè)試
context_text.go,x_test.go
是單元測(cè)試, example_test.go
是示例,benchmark_test.go是基準(zhǔn)測(cè)試, net_test.go展示了deadline對(duì)net包的支持.
先看單元測(cè)試的context_text.go.
type testingT interface {} type otherContext struct {} func quiescent(t testingT) time.Duration {} func XTestBackground(t testingT) {} func XTestTODO(t testingT) {} func XTestWithCancel(t testingT) {} func contains(m map[canceler]struct{}, key canceler) bool {} func XTestParentFinishesChild(t testingT) {} func XTestChildFinishesFirst(t testingT) {} func testDeadline(c Context, name string, t testingT) {} func XTestDeadline(t testingT) {} func XTestTimeout(t testingT) {} func XTestCanceledTimeout(t testingT) {} func XTestValues(t testingT) {} func XTestAllocs(t testingT, testingShort func() bool, testingAllocsPerRun func(int, func()) float64) {} func XTestSimultaneousCancels(t testingT) {} func XTestInterlockedCancels(t testingT) {} func XTestLayersCancel(t testingT) {} func XTestLayersTimeout(t testingT) {} func XTestCancelRemoves(t testingT) {} func XTestWithCancelCanceledParent(t testingT) {} func XTestWithValueChecksKey(t testingT) {} func XTestInvalidDerivedFail(t testingT) {} func recoveredValue(fn func()) (v interface{}) {} func XTestDeadlineExceededSupportsTimeout(t testingT) {} type myCtx struct {} type myDoneCtx struct {} func (d *myDoneCtx) Done() <-chan struct{} {} func XTestCustomContextGoroutines(t testingT) {}
這暴露的大多測(cè)試函數(shù)的參數(shù)類型是testingT接口類型,但這個(gè)源文件中沒(méi)有實(shí)現(xiàn)testingT
接口的,
func TestBackground(t *testing.T) ? ? ? ? ? ? ? ? ? ? ?{ XTestBackground(t) } func TestTODO(t *testing.T) ? ? ? ? ? ? ? ? ? ? ? ? ? ?{ XTestTODO(t) } func TestWithCancel(t *testing.T) ? ? ? ? ? ? ? ? ? ? ?{ XTestWithCancel(t) } func TestParentFinishesChild(t *testing.T) ? ? ? ? ? ? { XTestParentFinishesChild(t) } func TestChildFinishesFirst(t *testing.T) ? ? ? ? ? ? ?{ XTestChildFinishesFirst(t) } func TestDeadline(t *testing.T) ? ? ? ? ? ? ? ? ? ? ? ?{ XTestDeadline(t) } func TestTimeout(t *testing.T) ? ? ? ? ? ? ? ? ? ? ? ? { XTestTimeout(t) } func TestCanceledTimeout(t *testing.T) ? ? ? ? ? ? ? ? { XTestCanceledTimeout(t) } func TestValues(t *testing.T) ? ? ? ? ? ? ? ? ? ? ? ? ?{ XTestValues(t) } func TestAllocs(t *testing.T) ? ? ? ? ? ? ? ? ? ? ? ? ?{ XTestAllocs(t, testing.Short, testing.AllocsPerRun) } func TestSimultaneousCancels(t *testing.T) ? ? ? ? ? ? { XTestSimultaneousCancels(t) } func TestInterlockedCancels(t *testing.T) ? ? ? ? ? ? ?{ XTestInterlockedCancels(t) } func TestLayersCancel(t *testing.T) ? ? ? ? ? ? ? ? ? ?{ XTestLayersCancel(t) } func TestLayersTimeout(t *testing.T) ? ? ? ? ? ? ? ? ? { XTestLayersTimeout(t) } func TestCancelRemoves(t *testing.T) ? ? ? ? ? ? ? ? ? { XTestCancelRemoves(t) } func TestWithCancelCanceledParent(t *testing.T) ? ? ? ?{ XTestWithCancelCanceledParent(t) } func TestWithValueChecksKey(t *testing.T) ? ? ? ? ? ? ?{ XTestWithValueChecksKey(t) } func TestInvalidDerivedFail(t *testing.T) ? ? ? ? ? ? ?{ XTestInvalidDerivedFail(t) } func TestDeadlineExceededSupportsTimeout(t *testing.T) { XTestDeadlineExceededSupportsTimeout(t) } func TestCustomContextGoroutines(t *testing.T) ? ? ? ? { XTestCustomContextGoroutines(t) }
這是x_test.go
的內(nèi)容,直接是用testing.T
類型來(lái)實(shí)現(xiàn)testingT接口.
那先分析一下testing.T對(duì)testingT接口的實(shí)現(xiàn).
type T struct { ? common ? isParallel bool ? context ? ?*testContext } func (t *T) Deadline() (deadline time.Time, ok bool) { ? deadline = t.context.deadline ? return deadline, !deadline.IsZero() }
注意:testing.T.context不是context.Context的實(shí)現(xiàn)類型, Deadline()返回了t.context中存儲(chǔ)的deadline信息.
testing.T內(nèi)嵌了testing.common,大部分方法集都來(lái)至common:
Error(args ...interface{}) Errorf(format string, args ...interface{}) Fail() FailNow() Failed() bool Fatal(args ...interface{}) Fatalf(format string, args ...interface{}) Helper() Log(args ...interface{}) Logf(format string, args ...interface{}) Name() string Skip(args ...interface{}) SkipNow() Skipf(format string, args ...interface{}) Skipped() bool
Parallel()
是由testing.T
實(shí)現(xiàn),某個(gè)測(cè)試用例多次重復(fù)執(zhí)行時(shí), 可啟用并發(fā)參數(shù).
原文鏈接:https://juejin.cn/post/7062246261667135518
相關(guān)推薦
- 2022-10-25 Android自定義View實(shí)現(xiàn)水波紋擴(kuò)散效果_Android
- 2022-10-26 如何查看git分支從哪個(gè)源分支拉的_相關(guān)技巧
- 2022-04-26 Python中Enum使用的幾點(diǎn)注意事項(xiàng)_python
- 2022-09-22 C語(yǔ)言自定義類型——枚舉,聯(lián)合體
- 2022-06-21 Flutter實(shí)現(xiàn)單選,復(fù)選和開(kāi)關(guān)組件的示例代碼_Android
- 2023-06-04 pandas.DataFrame中提取特定類型dtype的列_python
- 2022-09-29 Python?pkg_resources模塊動(dòng)態(tài)加載插件實(shí)例分析_python
- 2022-12-30 解決React報(bào)錯(cuò)The?tag?is?unrecognized?in?this?browser_R
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過(guò)濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支