door 余小章 's 6 jaren geleden
731
Meer zoals dit
非對稱式加密
圖片
亂數
table.CreateInstance
table.CreateSet
Table.CompareToSet(collection)
Table.CompareToInstance(row)
目的是用來共享不同步驟的資料資料
FeatureContext和ScenarioContext不同的之處在於物件生命週期
ScenarioContext.Current.Get("key")
ScenarioContext.Current.Set(value,"key")
1 - [BeforeTestRun] => static method 2 - [BeforeFeature] 3 - [BeforeScenario] or [Before] 4 - [BeforeScenarioBlock] 5 - [BeforeStep] 6 - [AfterStep] 7 - [AfterScenarioBlock] 8 - [AfterScenario] or [After] 9 - [AfterFeature] 10 - [AfterTestRun]
Hook靠著 [Binding] 來運作
[Binding] public class Test{}
http://specflow.org/documentation/Scoped-bindings/
靠著描述來Binding測試方法,只要步驟的描述能Binding的到,就可以使用,Scope用來控制測試方法能給誰用
Bindings在有Specflow專案例面是一個全域物件
多欄多筆資料table
Table可以轉成強型別物件
[Given(@"the following books")] public void GivenTheFollowingBooks(Table table) { ... }
Given the following books |Author |Title | |Martin Fowler |Analysis Patterns | |Gojko Adzic |Bridging the Communication Gap |
工具自動產生只是輔助,最終你還是要改成你需要的型別
Feature描述中用雙引號包起來,工具所產生的測試方法會帶有字串參數;用數字會產生int
Scenario: View last incidents Given the user "Linda" exists And I log in as "Linda" When I go to the incident page
Hook的描述用(.*),則代表參數
[Given(@"the user (.*) exists")] public void GivenTheUserExists(string name) { // ... }
Given => Arrange
When => Act
Then => Assert
Behavior-driven development,BDD
Scenario 1: 標題(描述場景的單行文字) Given [上下文] And [更多的上下文]... When [事件] Then [结果] And [其他结果]
用來驗證故事,Scenario都完成了,才代表功能完成
Story: 標題(描述故事的單行文字) As a [WHO 角色:誰要使用這個功能] I want [WHAT願望:需要完成甚麼樣的功能 ] So that [WHY利益:為什麼需要這個功能]
用極度抽象的方式來描述文件
描述使用者、系統或軟體購買者,有價值的功能
使用者故事,系統對某方面的功能稱為"故事"
Test-driven development,TDD
驗證結果
調用目標
準備前置作業
解除耦合、降低相依
NSubstitute
Mock Framework
用來動態建立模擬物件,然後注入目標
必須是 interface 或 virtual
必須是 interface 或 virtual
用來動態建立模擬物件,然後注入目標
Mock Framework
DI (Dependency Injection)實現的方式
欄位
屬性
方法
建構函數
委派
介面
檔案
Test
InternalsVisibleTo
DI (Dependency Injection)實現的方式
用在測試
讓特定的專案(Component),可以存取 internal 的成員
欄位 屬性 方法 建構函數 委派 介面 IO(檔案、SQL)
DI就是實現IoC的技巧
DI (Dependency Injection)依賴注入
IoC (Inversion of Control)
反轉控制
由外部決定物件生成的方式
SOLID的D,依賴倒置原則 (D.I.P)
SOLID的D,依賴倒置原則 (D.I.P)
由外部決定物件生成的方式
IoC (Inversion of Control)反轉控制
DBA會不習慣
mapper.Map
var mapper = config.CreateMapper()
var config = new MapperConfiguration
Mapper.Map
Mapper.Initialize
匿名型別
Fluent Assertions
不要在測試程式寫catch唷
object.ReferenceEquals(actual, actual)
object.Equals(expected, actual)
Assert.AreSame(expected,actual) => 兩個物件是否同一個物件
Assert.AreEqual(expected,actual) => 兩個物件是否相等
Ctrl+R, Ctrl+A 偵錯所有測試
Ctrl+R, A 執行所有測試
Ctrl+R, Ctrl+T 偵錯單一測試
Ctrl+R, T 執行單一測試
1 - Runs [AssemblyInitialize]
2 - Randomly runs a [ClassInitialize]
3 - Runs the class [TestInitialize]
4 - Randomly runs a [TestMethod] from that class
5 - Runs the class [TestCleanup]
Repeat 3 through 5 for each TestMethod in the class
Repeat 2 through 5 for each test class
6 - Runs all classes [ClassCleanup] methods
7 - Runs [AssemblyCleanup]
[TestClass] public class Test{}
各層之間具有一定的"獨立性",維持之間溝通的介面不變,各層可以根據具體問題各自實作,而不需要其他層也必須做出相應調整
IO瓶頸
網路
記憶體
分流
資源不足時,用Web Service/Web API掛載
輕易的模擬依賴的物件
容易寫測試
合理的分層有助於分工開發與維護,哪一層壞了就改哪一層
可以將各層次間的相依性減到最低
分支主題
以替換某一層的具體實現,只要前後提供的服務相同即可
各Layer之間的資料模型定義
資料倉儲
Text
Excel
SQL
I/O
Repository/Data Access/Persistence/PO/DAO
存取資料
商業邏輯,流程控制
展現層,使用者操作介面,介面的連動效果
細節應依賴抽象
抽象不應依賴細節
高層模組不應依賴低層模組,兩者都應依賴其抽象
客戶端不應該依賴他不需要的介面,類別間的依賴關係應該建立在最小的介面上。
一個物件應對其他物件有最少的了解。通俗來說就是我只要知道你提供這麼多public方法,其他我都一概不關心。
父類別能出現的地方,子類別就可以出現,而且替換成子類別不會造成錯誤或異常。
應該透過擴展來實做變化,而不是修改已有的程式碼來實作變化
用“職責”或“變化原因”來衡量介面或類別設計,也可以套用到方法
寫測試的重點是在於隔離技巧(mock),這技巧學會了,設計物件及架構的能力無形之間就會提升
驗證執行結果
執行步驟
輸入資料
結果是穩定的,不會因為環境而影響結果
任何人、任何地點都能運行
能自動化,可重複執行
結果,A功能改好了,但BCD功能壞掉了,可怕的是BCD壞了你還不知道....
好花時間、好麻煩阿,最後,只針對那個需求按A按鈕
把UI打開,將所有的按鈕都按過一遍,下次需求異動的時候,在手動按過一遍
對表單的CUD操作,會開啟SSMS,針對需求下Insert、Update(還原)、Select(人眼比對),存檔,然後下次就忘了這段Script在是幹嘛的,然後再重寫一次..
在UI彈跳出一個警告視窗,觀看視窗的結果,看完了(人眼比對)再把它註解起來
既然要測,為何不挺?
寫好的東西要不要測?
只要有Production Code,就應該被驗證,而不是用簡單與否來當旗標
最有效確認需求的方法之一就是利用測試個案. 就像是在測試一個系統一樣, 來測試需求是否正確. 也就是說, 你可以用範例來闡釋需求, 把範例變成測試, 然後使用測試驗證需求」
為了避免浪費,必須要做需求確認
一個簡單的需求,大家的想法就不一樣..
但其實是,最簡單的事往往最花時間
測試的重點不是寫測試,而是需求
需求不明確,幹嘛要花時間寫測試
為什麼需求不明確就要開始寫程式?而不是先釐清問題?
因為,寫了測試還是沒辦法達到User需求阿,幹嘛寫它
你可能搞錯對象了