Soumettre la recherche
Mettre en ligne
外部環境への依存をテストする
•
5 j'aime
•
2,177 vues
S
Shunsuke Maeda
Suivre
Golangを使ってアプリを開発する際に、 外部環境への依存をテストするときのTIPS集です
Lire moins
Lire la suite
Logiciels
Affichage du diaporama
Signaler
Partager
Affichage du diaporama
Signaler
Partager
1 sur 63
Télécharger maintenant
Télécharger pour lire hors ligne
Recommandé
Go言語のスライスを理解しよう
Go言語のスライスを理解しよう
Yasutaka Kawamoto
Goの時刻に関するテスト
Goの時刻に関するテスト
Kentaro Kawano
pg_hint_planを知る(第37回PostgreSQLアンカンファレンス@オンライン 発表資料)
pg_hint_planを知る(第37回PostgreSQLアンカンファレンス@オンライン 発表資料)
NTT DATA Technology & Innovation
日本語テストメソッドについて
日本語テストメソッドについて
kumake
Go言語によるwebアプリの作り方
Go言語によるwebアプリの作り方
Yasutaka Kawamoto
C++からWebRTC (DataChannel)を利用する
C++からWebRTC (DataChannel)を利用する
祐司 伊藤
BuildKitによる高速でセキュアなイメージビルド
BuildKitによる高速でセキュアなイメージビルド
Akihiro Suda
Microsoft Graph APIを活用した社内アプリケーション開発
Microsoft Graph APIを活用した社内アプリケーション開発
Yuki Hattori
Recommandé
Go言語のスライスを理解しよう
Go言語のスライスを理解しよう
Yasutaka Kawamoto
Goの時刻に関するテスト
Goの時刻に関するテスト
Kentaro Kawano
pg_hint_planを知る(第37回PostgreSQLアンカンファレンス@オンライン 発表資料)
pg_hint_planを知る(第37回PostgreSQLアンカンファレンス@オンライン 発表資料)
NTT DATA Technology & Innovation
日本語テストメソッドについて
日本語テストメソッドについて
kumake
Go言語によるwebアプリの作り方
Go言語によるwebアプリの作り方
Yasutaka Kawamoto
C++からWebRTC (DataChannel)を利用する
C++からWebRTC (DataChannel)を利用する
祐司 伊藤
BuildKitによる高速でセキュアなイメージビルド
BuildKitによる高速でセキュアなイメージビルド
Akihiro Suda
Microsoft Graph APIを活用した社内アプリケーション開発
Microsoft Graph APIを活用した社内アプリケーション開発
Yuki Hattori
GoによるWebアプリ開発のキホン
GoによるWebアプリ開発のキホン
Akihiko Horiuchi
サーバーサイド Kotlin のテストフレームワーク事情
サーバーサイド Kotlin のテストフレームワーク事情
Shinya Mochida
性能測定道 実践編
性能測定道 実践編
Yuto Hayamizu
プログラムの処方箋~健康なコードと病んだコード
プログラムの処方箋~健康なコードと病んだコード
Shigenori Sagawa
Dockerからcontainerdへの移行
Dockerからcontainerdへの移行
Kohei Tokunaga
PySparkによるジョブを、より速く、よりスケーラブルに実行するための最善の方法 ※講演は翻訳資料にて行います。 - Getting the Best...
PySparkによるジョブを、より速く、よりスケーラブルに実行するための最善の方法 ※講演は翻訳資料にて行います。 - Getting the Best...
Holden Karau
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
Takuto Wada
Docker道場オンライン#1 Docker基礎概念と用語の理解
Docker道場オンライン#1 Docker基礎概念と用語の理解
Masahito Zembutsu
マイクロサービスバックエンドAPIのためのRESTとgRPC
マイクロサービスバックエンドAPIのためのRESTとgRPC
disc99_
Building the Game Server both API and Realtime via c#
Building the Game Server both API and Realtime via c#
Yoshifumi Kawai
Redisの特徴と活用方法について
Redisの特徴と活用方法について
Yuji Otani
TLS 1.3 と 0-RTT のこわ〜い話
TLS 1.3 と 0-RTT のこわ〜い話
Kazuho Oku
ソーシャルゲーム案件におけるDB分割のPHP実装
ソーシャルゲーム案件におけるDB分割のPHP実装
infinite_loop
Googleのインフラ技術から考える理想のDevOps
Googleのインフラ技術から考える理想のDevOps
Etsuji Nakai
コンポーネント指向による、Reactのベストプラクティスとバッドプラクティス
コンポーネント指向による、Reactのベストプラクティスとバッドプラクティス
Kohei Asai
世界一わかりやすいClean Architecture
世界一わかりやすいClean Architecture
Atsushi Nakamura
Python製BDDツールで自動化してみた
Python製BDDツールで自動化してみた
KeijiUehata1
Dockerライフサイクルの基礎 地雷を踏み抜けろ!
Dockerライフサイクルの基礎 地雷を踏み抜けろ!
Masahito Zembutsu
DockerでWordPressサイトを開発してみよう
DockerでWordPressサイトを開発してみよう
mookjp
PostgreSQL Unconference #29 Unicode IVS
PostgreSQL Unconference #29 Unicode IVS
Noriyoshi Shinoda
Building Go Web Apps
Building Go Web Apps
Mark
HashiCorp Vault Plugin Infrastructure
HashiCorp Vault Plugin Infrastructure
Nicolas Corrarello
Contenu connexe
Tendances
GoによるWebアプリ開発のキホン
GoによるWebアプリ開発のキホン
Akihiko Horiuchi
サーバーサイド Kotlin のテストフレームワーク事情
サーバーサイド Kotlin のテストフレームワーク事情
Shinya Mochida
性能測定道 実践編
性能測定道 実践編
Yuto Hayamizu
プログラムの処方箋~健康なコードと病んだコード
プログラムの処方箋~健康なコードと病んだコード
Shigenori Sagawa
Dockerからcontainerdへの移行
Dockerからcontainerdへの移行
Kohei Tokunaga
PySparkによるジョブを、より速く、よりスケーラブルに実行するための最善の方法 ※講演は翻訳資料にて行います。 - Getting the Best...
PySparkによるジョブを、より速く、よりスケーラブルに実行するための最善の方法 ※講演は翻訳資料にて行います。 - Getting the Best...
Holden Karau
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
Takuto Wada
Docker道場オンライン#1 Docker基礎概念と用語の理解
Docker道場オンライン#1 Docker基礎概念と用語の理解
Masahito Zembutsu
マイクロサービスバックエンドAPIのためのRESTとgRPC
マイクロサービスバックエンドAPIのためのRESTとgRPC
disc99_
Building the Game Server both API and Realtime via c#
Building the Game Server both API and Realtime via c#
Yoshifumi Kawai
Redisの特徴と活用方法について
Redisの特徴と活用方法について
Yuji Otani
TLS 1.3 と 0-RTT のこわ〜い話
TLS 1.3 と 0-RTT のこわ〜い話
Kazuho Oku
ソーシャルゲーム案件におけるDB分割のPHP実装
ソーシャルゲーム案件におけるDB分割のPHP実装
infinite_loop
Googleのインフラ技術から考える理想のDevOps
Googleのインフラ技術から考える理想のDevOps
Etsuji Nakai
コンポーネント指向による、Reactのベストプラクティスとバッドプラクティス
コンポーネント指向による、Reactのベストプラクティスとバッドプラクティス
Kohei Asai
世界一わかりやすいClean Architecture
世界一わかりやすいClean Architecture
Atsushi Nakamura
Python製BDDツールで自動化してみた
Python製BDDツールで自動化してみた
KeijiUehata1
Dockerライフサイクルの基礎 地雷を踏み抜けろ!
Dockerライフサイクルの基礎 地雷を踏み抜けろ!
Masahito Zembutsu
DockerでWordPressサイトを開発してみよう
DockerでWordPressサイトを開発してみよう
mookjp
PostgreSQL Unconference #29 Unicode IVS
PostgreSQL Unconference #29 Unicode IVS
Noriyoshi Shinoda
Tendances
(20)
GoによるWebアプリ開発のキホン
GoによるWebアプリ開発のキホン
サーバーサイド Kotlin のテストフレームワーク事情
サーバーサイド Kotlin のテストフレームワーク事情
性能測定道 実践編
性能測定道 実践編
プログラムの処方箋~健康なコードと病んだコード
プログラムの処方箋~健康なコードと病んだコード
Dockerからcontainerdへの移行
Dockerからcontainerdへの移行
PySparkによるジョブを、より速く、よりスケーラブルに実行するための最善の方法 ※講演は翻訳資料にて行います。 - Getting the Best...
PySparkによるジョブを、より速く、よりスケーラブルに実行するための最善の方法 ※講演は翻訳資料にて行います。 - Getting the Best...
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
Docker道場オンライン#1 Docker基礎概念と用語の理解
Docker道場オンライン#1 Docker基礎概念と用語の理解
マイクロサービスバックエンドAPIのためのRESTとgRPC
マイクロサービスバックエンドAPIのためのRESTとgRPC
Building the Game Server both API and Realtime via c#
Building the Game Server both API and Realtime via c#
Redisの特徴と活用方法について
Redisの特徴と活用方法について
TLS 1.3 と 0-RTT のこわ〜い話
TLS 1.3 と 0-RTT のこわ〜い話
ソーシャルゲーム案件におけるDB分割のPHP実装
ソーシャルゲーム案件におけるDB分割のPHP実装
Googleのインフラ技術から考える理想のDevOps
Googleのインフラ技術から考える理想のDevOps
コンポーネント指向による、Reactのベストプラクティスとバッドプラクティス
コンポーネント指向による、Reactのベストプラクティスとバッドプラクティス
世界一わかりやすいClean Architecture
世界一わかりやすいClean Architecture
Python製BDDツールで自動化してみた
Python製BDDツールで自動化してみた
Dockerライフサイクルの基礎 地雷を踏み抜けろ!
Dockerライフサイクルの基礎 地雷を踏み抜けろ!
DockerでWordPressサイトを開発してみよう
DockerでWordPressサイトを開発してみよう
PostgreSQL Unconference #29 Unicode IVS
PostgreSQL Unconference #29 Unicode IVS
Similaire à 外部環境への依存をテストする
Building Go Web Apps
Building Go Web Apps
Mark
HashiCorp Vault Plugin Infrastructure
HashiCorp Vault Plugin Infrastructure
Nicolas Corrarello
CouchDB on Android
CouchDB on Android
Sven Haiges
Net/http and the http.handler interface
Net/http and the http.handler interface
Joakim Gustin
Net/http and the http.handler interface
Net/http and the http.handler interface
Evolve
33rd Degree 2013, Bad Tests, Good Tests
33rd Degree 2013, Bad Tests, Good Tests
Tomek Kaczanowski
Aplicações assíncronas no Android com Coroutines & Jetpack
Aplicações assíncronas no Android com Coroutines & Jetpack
Nelson Glauber Leal
Non Blocking I/O for Everyone with RxJava
Non Blocking I/O for Everyone with RxJava
Frank Lyaruu
Online Meetup: Why should container system / platform builders care about con...
Online Meetup: Why should container system / platform builders care about con...
Docker, Inc.
The Ring programming language version 1.5.4 book - Part 40 of 185
The Ring programming language version 1.5.4 book - Part 40 of 185
Mahmoud Samir Fayed
2013 DevFest Vienna - Bad Tests, Good Tests
2013 DevFest Vienna - Bad Tests, Good Tests
Tomek Kaczanowski
Wprowadzenie do technologi Big Data i Apache Hadoop
Wprowadzenie do technologi Big Data i Apache Hadoop
Sages
Job Queue in Golang
Job Queue in Golang
Bo-Yi Wu
JJUG CCC 2011 Spring
JJUG CCC 2011 Spring
Kiyotaka Oku
Clean coding-practices
Clean coding-practices
John Ferguson Smart Limited
服务框架: Thrift & PasteScript
服务框架: Thrift & PasteScript
Qiangning Hong
Functional programming using underscorejs
Functional programming using underscorejs
偉格 高
Deep Dumpster Diving
Deep Dumpster Diving
RonnBlack
RESTful Web Applications with Google Go
RESTful Web Applications with Google Go
Frank Müller
NET Systems Programming Learned the Hard Way.pptx
NET Systems Programming Learned the Hard Way.pptx
petabridge
Similaire à 外部環境への依存をテストする
(20)
Building Go Web Apps
Building Go Web Apps
HashiCorp Vault Plugin Infrastructure
HashiCorp Vault Plugin Infrastructure
CouchDB on Android
CouchDB on Android
Net/http and the http.handler interface
Net/http and the http.handler interface
Net/http and the http.handler interface
Net/http and the http.handler interface
33rd Degree 2013, Bad Tests, Good Tests
33rd Degree 2013, Bad Tests, Good Tests
Aplicações assíncronas no Android com Coroutines & Jetpack
Aplicações assíncronas no Android com Coroutines & Jetpack
Non Blocking I/O for Everyone with RxJava
Non Blocking I/O for Everyone with RxJava
Online Meetup: Why should container system / platform builders care about con...
Online Meetup: Why should container system / platform builders care about con...
The Ring programming language version 1.5.4 book - Part 40 of 185
The Ring programming language version 1.5.4 book - Part 40 of 185
2013 DevFest Vienna - Bad Tests, Good Tests
2013 DevFest Vienna - Bad Tests, Good Tests
Wprowadzenie do technologi Big Data i Apache Hadoop
Wprowadzenie do technologi Big Data i Apache Hadoop
Job Queue in Golang
Job Queue in Golang
JJUG CCC 2011 Spring
JJUG CCC 2011 Spring
Clean coding-practices
Clean coding-practices
服务框架: Thrift & PasteScript
服务框架: Thrift & PasteScript
Functional programming using underscorejs
Functional programming using underscorejs
Deep Dumpster Diving
Deep Dumpster Diving
RESTful Web Applications with Google Go
RESTful Web Applications with Google Go
NET Systems Programming Learned the Hard Way.pptx
NET Systems Programming Learned the Hard Way.pptx
Plus de Shunsuke Maeda
私とOSS活動とPerl
私とOSS活動とPerl
Shunsuke Maeda
テストを書いてGradleプラグインの開発効率を改善しよう
テストを書いてGradleプラグインの開発効率を改善しよう
Shunsuke Maeda
DroidKaigi_devicefarm
DroidKaigi_devicefarm
Shunsuke Maeda
iOSにおけるコードレビューを一歩先へ進める
iOSにおけるコードレビューを一歩先へ進める
Shunsuke Maeda
iOSで利用できるデバイスファームのメリット・デメリットの紹介
iOSで利用できるデバイスファームのメリット・デメリットの紹介
Shunsuke Maeda
Pull request時の画面差分取得の自動化
Pull request時の画面差分取得の自動化
Shunsuke Maeda
Dangerでpull requestレビューの指摘事項を減らす
Dangerでpull requestレビューの指摘事項を減らす
Shunsuke Maeda
Plus de Shunsuke Maeda
(7)
私とOSS活動とPerl
私とOSS活動とPerl
テストを書いてGradleプラグインの開発効率を改善しよう
テストを書いてGradleプラグインの開発効率を改善しよう
DroidKaigi_devicefarm
DroidKaigi_devicefarm
iOSにおけるコードレビューを一歩先へ進める
iOSにおけるコードレビューを一歩先へ進める
iOSで利用できるデバイスファームのメリット・デメリットの紹介
iOSで利用できるデバイスファームのメリット・デメリットの紹介
Pull request時の画面差分取得の自動化
Pull request時の画面差分取得の自動化
Dangerでpull requestレビューの指摘事項を減らす
Dangerでpull requestレビューの指摘事項を減らす
Dernier
%in Soweto+277-882-255-28 abortion pills for sale in soweto
%in Soweto+277-882-255-28 abortion pills for sale in soweto
masabamasaba
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
masabamasaba
WSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
WSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
WSO2
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
masabamasaba
WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?
WSO2
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
VictoriaMetrics
Architecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the past
Papp Krisztián
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
masabamasaba
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
Jittipong Loespradit
tonesoftg
tonesoftg
lanshi9
WSO2CON2024 - It's time to go Platformless
WSO2CON2024 - It's time to go Platformless
WSO2
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...
WSO2
%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand
masabamasaba
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
masabamasaba
Announcing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK Software
Jim McKeeth
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
Shane Coughlan
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
masabamasaba
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
masabamasaba
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
masabamasaba
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2
Dernier
(20)
%in Soweto+277-882-255-28 abortion pills for sale in soweto
%in Soweto+277-882-255-28 abortion pills for sale in soweto
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
WSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
WSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Architecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the past
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
tonesoftg
tonesoftg
WSO2CON2024 - It's time to go Platformless
WSO2CON2024 - It's time to go Platformless
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...
%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
Announcing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK Software
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
外部環境への依存をテストする
1.
Golang.tokyo 2018/08/21 (Tue) ( @duck8823
)
2.
• • @duck8823 • • / • •
Kotlin • Golang
3.
• • @duck8823 • • • • Kotlin •
Golang
4.
• • @duck8823 • • • • Kotlin •
Golang
5.
CI • duck8823/duci • Golang •
Docker
6.
CI • duck8823/duci • Golang •
Docker
7.
CI • duck8823/duci • Golang •
Docker
8.
Webhooks (HTTP) Commit Status (HTTP)
9.
Webhooks (HTTP) Commit Status (HTTP)
10.
Webhooks (HTTP) Commit Status (HTTP)
11.
( ) • Incoming
HTTP Requests • Git Docker ( ) • • • Outgoing HTTP Requests
12.
13.
• Incoming HTTP
Requests • Git Docker ( ) ) • ( • • Outgoing HTTP Requests
14.
Incoming HTTP Requests func
HandlerFunc(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) body, _ := ioutil.ReadAll(r.Body) w.Write([]byte(fmt.Sprintf("Hello %s.", body))) } • HandlerFunc , . "
15.
HandlerFunc func Test_HandlerFunc(t *testing.T)
{ // given req := httptest.NewRequest("HELLO", "/", strings.NewReader("world")) rec := httptest.NewRecorder() // when HandlerFunc(rec, req) // then if rec.Code != http.StatusOK { t.Errorf("wont %+v, but got %+v", http.StatusOK, rec.Code) } if !reflect.DeepEqual(rec.Body.Bytes(), []byte("Hello world.")) { t.Errorf("wont %+v, but got %+v","Hello world.", string(rec.Body.Bytes())) } }
16.
HandlerFunc func Test_HandlerFunc(t *testing.T)
{ // given req := httptest.NewRequest("HELLO", "/", strings.NewReader("world")) rec := httptest.NewRecorder() // when HandlerFunc(rec, req) // then if rec.Code != http.StatusOK { t.Errorf("wont %+v, but got %+v", http.StatusOK, rec.Code) } if !reflect.DeepEqual(rec.Body.Bytes(), []byte("Hello world.")) { t.Errorf("wont %+v, but got %+v","Hello world.", string(rec.Body.Bytes())) } } http.ResponseWriter (*httptest.ResponseRecorder) *http.Request
17.
HandlerFunc func Test_HandlerFunc(t *testing.T)
{ // given req := httptest.NewRequest("HELLO", "/", strings.NewReader("world")) rec := httptest.NewRecorder() // when HandlerFunc(rec, req) // then if rec.Code != http.StatusOK { t.Errorf("wont %+v, but got %+v", http.StatusOK, rec.Code) } if !reflect.DeepEqual(rec.Body.Bytes(), []byte("Hello world.")) { t.Errorf("wont %+v, but got %+v","Hello world.", string(rec.Body.Bytes())) } }
18.
HandlerFunc func Test_HandlerFunc(t *testing.T)
{ // given req := httptest.NewRequest("HELLO", "/", strings.NewReader("world")) rec := httptest.NewRecorder() // when HandlerFunc(rec, req) // then if rec.Code != http.StatusOK { t.Errorf("wont %+v, but got %+v", http.StatusOK, rec.Code) } if !reflect.DeepEqual(rec.Body.Bytes(), []byte("Hello world.")) { t.Errorf("wont %+v, but got %+v","Hello world.", string(rec.Body.Bytes())) } } *httptest.ResponseRecorder
19.
chi HandlerFunc • URL
("/{param}") HandlerFunc go-chi/chi // "/{param}" func ChiHandlerFunc(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) param := chi.URLParam(r.Context(), "param") w.Write([]byte(fmt.Sprintf("Hello %s.", param))) }
20.
chi HandlerFunc func TestChiHandlerFunc(t
*testing.T) { // given ctx := chi.NewContext() ctx.Params.Add("param", "world") req := httptest.NewRequest("HELLO", "/", nil).WithContext(ctx) rec := httptest.NewRecorder() // when ChiHandlerFunc(rec, req) // then // ...check rec }
21.
chi HandlerFunc func TestChiHandlerFunc(t
*testing.T) { // given ctx := chi.NewContext() ctx.Params.Add("param", "world") req := httptest.NewRequest("HELLO", "/", nil).WithContext(ctx) rec := httptest.NewRecorder() // when ChiHandlerFunc(rec, req) // then // ...check rec } context.Context
22.
chi HandlerFunc func TestChiHandlerFunc(t
*testing.T) { // given ctx := chi.NewContext() ctx.Params.Add("param", "world") req := httptest.NewRequest("HELLO", "/", nil).WithContext(ctx) rec := httptest.NewRecorder() // when ChiHandlerFunc(rec, req) // then // ...check rec } *http.Request context.Context
23.
chi HandlerFunc func TestChiHandlerFunc(t
*testing.T) { // given ctx := chi.NewContext() ctx.Params.Add("param", "world") req := httptest.NewRequest("HELLO", "/", nil).WithContext(ctx) rec := httptest.NewRecorder() // when ChiHandlerFunc(rec, req) // then // ...check rec }
24.
Incoming HTTP Requests •
httptest • URL
25.
• Incoming HTTP
Requests • Git Docker ( ) ) • ( • • Outgoing HTTP Requests
26.
Git Docker (3rd
) • src-d/go-git moby/moby • •
27.
type docker struct
{ moby *client.Client } func (d *docker) Run(image string, cmd ...string) { ctx := context.Background() _, err := d.moby.ImagePull(ctx, image, types.ImagePullOptions{}) con, _ := d.moby.ContainerCreate(ctx, &container.Config{ Image: image, Cmd: cmd }, nil, nil, "") err := d.moby.ContainerStart(ctx, con.ID, types.ContainerStartOptions{}) } • ( docker run )
28.
type docker struct
{ moby *client.Client } func (d *docker) Run(image string, cmd ...string) { ctx := context.Background() _, err := d.moby.ImagePull(ctx, image, types.ImagePullOptions{}) con, _ := d.moby.ContainerCreate(ctx, &container.Config{ Image: image, Cmd: cmd }, nil, nil, "") err := d.moby.ContainerStart(ctx, con.ID, types.ContainerStartOptions{}) } • ( docker run )
29.
type docker struct
{ moby *client.Client } func (d *docker) Run(image string, cmd ...string) { ctx := context.Background() _, err := d.moby.ImagePull(ctx, image, types.ImagePullOptions{}) con, _ := d.moby.ContainerCreate(ctx, &container.Config{ Image: image, Cmd: cmd }, nil, nil, "") err := d.moby.ContainerStart(ctx, con.ID, types.ContainerStartOptions{}) } • ( docker run )
30.
type docker struct
{ moby *client.Client } func (d *docker) Run(image string, cmd ...string) { ctx := context.Background() _, err := d.moby.ImagePull(ctx, image, types.ImagePullOptions{}) con, _ := d.moby.ContainerCreate(ctx, &container.Config{ Image: image, Cmd: cmd }, nil, nil, "") err := d.moby.ContainerStart(ctx, con.ID, types.ContainerStartOptions{}) } • ( docker run )
31.
type docker struct
{ moby *client.Client } func (d *docker) Run(image string, cmd ...string) { ctx := context.Background() _, err := d.moby.ImagePull(ctx, image, types.ImagePullOptions{}) con, _ := d.moby.ContainerCreate(ctx, &container.Config{ Image: image, Cmd: cmd }, nil, nil, "") err := d.moby.ContainerStart(ctx, con.ID, types.ContainerStartOptions{}) } • ( docker run )
32.
type docker struct
{ moby *client.Client } func (d *docker) Run(image string, cmd ...string) { ctx := context.Background() _, err := d.moby.ImagePull(ctx, image, types.ImagePullOptions{}) con, _ := d.moby.ContainerCreate(ctx, &container.Config{ Image: image, Cmd: cmd }, nil, nil, "") err := d.moby.ContainerStart(ctx, con.ID, types.ContainerStartOptions{}) } . •
33.
Mock • *client.Client type Moby
interface { ImagePull(...) (...) ContainerCreate(...) (container.ContainerCreateCreatedBody, error) ContainerStart(...) error } type docker struct { moby Moby }
34.
Mock • google/mock/gomock func TestDocker_Run(t
*testing.T) { ctrl := gomock.NewController(t) mockMoby := NewMockMoby(ctrl) mockMoby.EXPECT(). ImagePull(gomock.Any(), gomock.Any(), gomock.Any()). AnyTimes(). Return(nil, errors.New("error image pull")) docker := &docker{moby: mockMoby} docker.Run("centos", "echo", "hello world") }
35.
Git Docker (3rd
) • • gomock • ( mock )
36.
• Incoming HTTP
Requests • Git Docker ( ) ) • ( • • Outgoing HTTP Requests
37.
package logger var Writer
io.Writer = os.Stdout func Debug(message string) { fmt.Fprintf(Writer, "[DEBUG] %sn", message) } • • ( os.Stdout ) io.Writer (*os.File )
38.
func TestDebug(t *testing.T)
{ // given reader, writer, _ := os.Pipe() logger.Writer = writer // and expected := "[DEBUG] Hello World.n" // when logger.Debug("Hello World.") // then writer.Close() actual, _ := ioutil.ReadAll(reader) if string(actual) != expected { t.Errorf("wont %s, but got %s", expected, actual) } }
39.
func TestDebug(t *testing.T)
{ // given reader, writer, _ := os.Pipe() logger.Writer = writer // and expected := "[DEBUG] Hello World.n" // when logger.Debug("Hello World.") // then writer.Close() actual, _ := ioutil.ReadAll(reader) if string(actual) != expected { t.Errorf("wont %s, but got %s", expected, actual) } } ) ( ).( 1 ( ( 2
40.
func TestDebug(t *testing.T)
{ // given reader, writer, _ := os.Pipe() logger.Writer = writer // and expected := "[DEBUG] Hello World.n" // when logger.Debug("Hello World.") // then writer.Close() actual, _ := ioutil.ReadAll(reader) if string(actual) != expected { t.Errorf("wont %s, but got %s", expected, actual) } }
41.
func TestDebug(t *testing.T)
{ // given reader, writer, _ := os.Pipe() logger.Writer = writer // and expected := "[DEBUG] Hello World.n" // when logger.Debug("Hello World.") // then writer.Close() actual, _ := ioutil.ReadAll(reader) if string(actual) != expected { t.Errorf("wont %s, but got %s", expected, actual) } }
42.
func TestDebug(t *testing.T)
{ // given reader, writer, _ := os.Pipe() logger.Writer = writer // and expected := "[DEBUG] Hello World.n" // when logger.Debug("Hello World.") // then writer.Close() actual, _ := ioutil.ReadAll(reader) if string(actual) != expected { t.Errorf("wont %s, but got %s", expected, actual) } }
43.
• io.Writer io.Pipe
44.
• Incoming HTTP
Requests • Git Docker ( ) ) • ( • • Outgoing HTTP Requests
45.
• func Debug(message string)
{ now := time.Now().Format("2006-01-02 15:04:05") fmt.Fprintf(Writer, "%s [DEBUG] %sn", now, message) }
46.
time.Now() • func Debug(message string)
{ now := clock.Now().Format("2006-01-02 15:04:05") fmt.Fprintf(Writer, "%s [DEBUG] %sn", now, message) } package clock import "time" var Now = func () time.Time { return time.Now() }
47.
func TestDebug(t *testing.T)
{ // given jst, _ := time.LoadLocation("Asia/Tokyo") clock.Now = func() time.Time { return time.Date(1987, time.March, 27, 09, 34, 00, 00, jst) } // and reader, writer, _ := os.Pipe() logger.Writer = writer // and expected := "1987-03-27 09:34:00 [DEBUG] Hello World.n" // when logger.Debug("Hello World.") // then // ... }
48.
func TestDebug(t *testing.T)
{ // given jst, _ := time.LoadLocation("Asia/Tokyo") clock.Now = func() time.Time { return time.Date(1987, time.March, 27, 09, 34, 00, 00, jst) } // and reader, writer, _ := os.Pipe() logger.Writer = writer // and expected := "1987-03-27 09:34:00 [DEBUG] Hello World.n" // when logger.Debug("Hello World.") // then // ... } .
49.
func TestDebug(t *testing.T)
{ // given jst, _ := time.LoadLocation("Asia/Tokyo") clock.Now = func() time.Time { return time.Date(1987, time.March, 27, 09, 34, 00, 00, jst) } // and reader, writer, _ := os.Pipe() logger.Writer = writer // and expected := "1987-03-27 09:34:00 [DEBUG] Hello World.n" // when logger.Debug("Hello World.") // then // ... }
50.
• ( ) •
time.Now
51.
• Incoming HTTP
Requests • Git Docker ( ) ) • ( • • Outgoing HTTP Requests
52.
Outgoing HTTP Requests •
EO • IL P • H / D G RA
53.
Outgoing HTTP Requests •
2 ) ) / ( ( func TestRequest(t *testing.T) { defer gock.Off() gock.New("http://example.com"). Post("/"). Reply(http.StatusOK) resp, _ := http.Post("http://example.com/", "application/json", nil) if resp.StatusCode != http.StatusOK { t.Errorf("wont %+v, but got %+v", http.StatusOK, resp.StatusCode) } }
54.
Outgoing HTTP Requests •
2 ) ) / ( ( func TestRequest(t *testing.T) { defer gock.Off() gock.New("http://example.com"). Post("/"). Reply(http.StatusOK) resp, _ := http.Post("http://example.com/", "application/json", nil) if resp.StatusCode != http.StatusOK { t.Errorf("wont %+v, but got %+v", http.StatusOK, resp.StatusCode) } }
55.
Outgoing HTTP Requests •
2 ) ) / ( ( func TestRequest(t *testing.T) { defer gock.Off() gock.New("http://example.com"). Post("/"). Reply(http.StatusOK) resp, _ := http.Post("http://example.com/", "application/json", nil) if resp.StatusCode != http.StatusOK { t.Errorf("wont %+v, but got %+v", http.StatusOK, resp.StatusCode) } }
56.
Outgoing HTTP Requests • •
57.
Webhooks (HTTP) Commit Status (HTTP)
58.
Webhooks (HTTP) Commit Status (HTTP)
59.
Webhooks (HTTP) Commit Status (HTTP)
60.
Webhooks (HTTP) Commit Status (HTTP)
61.
Webhooks (HTTP) Commit Status (HTTP) )& ) . &
&(
62.
Webhooks (HTTP) Commit Status (HTTP)
63.
• oc • H •
) ( k • P T • p • he ) (M
Télécharger maintenant