仔细想了下,觉得我问的这个问题维度可大可小,我就列一下我的一些困扰吧,求给建议或者分享经验。
以一个常见的web应用为例,我们一般会有数据层(完全对数据库的操作封装),面向客户端的业务接口,可能还会有面向第三方应用的API。那么如此一般你们会对那些维度进行测试呢?比如:
纠结主要在于虽然是不同层的测试,但是其实有非常多得荣誉在里面。比如数据层的一个createUser
方法的测试,对于API的HTTP层,无非可能直接就是把用户输入传到这个方法里面,然后返回这个方法的结果给客户端。
目前来说这些测试我都是手写,不知道大家是否有更加自动化的方式做这些测试。手写的话,我个人感觉问题有:
user
,app
,project
这些事例,那么这三者的所谓"增删改查"的用例基本上千篇一律,可能你写完user
,后面的app
和project
基本上就是复制过来然后改改名字了。js
describe( 'common', function(){ it( '添加用户', function( done ){ done(); }); it( '获取用户列表', function( done ){ done(); }); it( '获取某个用户', function( done ){ done(); }); it( '更新用户', function( done ){ done(); }); it( '删除用户', function( done ){ done(); }); });
感觉应该是比较常见的case,那么除了第一个“添加用户”外,可以看到,其他得所有case都需要“某个用户已经被添加”为前提。那么一般大家是怎么操作呢?我想到的思路有两种:
beforeEach
和afterEach
)欢迎发散分享经验!!!!
按照我的經驗:
所謂「業務流程」就是指類似「一個一般使用者註冊帳號、登入、修改密碼、發文、回覆」或「一個管理者帳號登入管理員面板、發文、回覆、刪除別人的發文」的流程。這樣的好處有很多,例如前面第一個流程的每個測試之間都共用同一個「普通使用者」,第二個流程都共用一個「管理員使用者」。
在一個流程內部共享資料可控性比較強,因為一個流程一般不會太長,而且內部的聯繫是比較大的。如果針對每個介面做測試的話,要么為每個測試單獨準備數據(很繁瑣),要么在所有測試之間共享數據(會出現很多全局變量,會很大程度上增加複雜度,測試之間互相也可能出現幹擾)。
應該確保每一個測試文件裡的測試是獨立的,用before 來定義這個文件所依賴的數據(例如這個文件的所有測試都需要先有一個用戶),你可以在其他文件定義一個
createTestAccount
的函數,接受一些選項,然後來產生符合要求的測試資料。這樣的好處就是你可以單獨執行某個測試,如果執行整個測試比較耗時的話,這樣可以解決很多時間,而且你也不必擔心測試之間會互相干擾。而且像是 mocha 這樣的函式庫,它是不擔保不同測試文件之間的運行順序的(雖然實際上會按字母順序運行),如果不同的測試文件之間有依賴會很麻煩。至於究竟是測 API 接口,還是測 Model, 這個就比較見仁見智了,不過「盡量把業務邏輯寫到 Model」裡這點是不會變的。
如果是測API 的話,那麼測試可以直接呼叫Model 裡的方法來準備資料和驗證測試結果(比起用API 來準備資料和驗證結果,可是要方便多了);如果是測Model 的話,因為大部分邏輯在Model 裡,所以Model 測完就可以基本保證沒有大問題了,因為Controller 裡的邏輯不多。
最後,請一定不要用「程式碼產生器」來產生測試程式碼。能夠用腳本生成,說明這些測試之間是有內在的邏輯的,你完全可以透過好的設計來避免出現重複的程式碼,畢竟 mocha 的測試也都是 JavaScript 程式碼,有什麼不能實現的呢?當然,測試的抽象程度不能太高了,要稍微直白一點,否則就會在「調試測試」上花太多時間,這之間需要自行做個權衡。
關於「程式碼產生器」請參考 程式設計師修練之道:從小工到專家 一書中的「邪惡的嚮導」一節,這本書中亦介紹了大量編寫自動測試的技巧。
我是這樣做的 API測試 這個沒辦法 必須要做
如果你的ORM活著類似的資料引擎 是自己開發的 保證這個沒問題就好了
複雜的資料操作 做一些單元測試 如果只是很簡單的功能 就沒必要了
當然TDD的話除外 對於創業團隊 測試很難特別全面的 掌握好一個度就好了~
我的理解是:啥不變測試啥
舉個例子你測試api,application public interface (short for api),這就是不變的,因為你public了,別人都在用,你如果接口改來改去,別人針對你的api調用的,能不報錯嗎?
單元測試其實測試也是這個[object or element or entry] interface,不會有人測試private method or protected method吧
針對業務邏輯的測試也是一樣,為啥,通常情況下,product沒有release的開發階段,業務邏輯應該是穩定,否則你怎麼做,東西還沒做完,需求已經變了
實作:找出業務邏輯來測試,如果你的業務邏輯寫在model裡面那就測試model,寫在service裡,你就測試service,
通常一個api應該是對應一個業務邏輯的,你測試了業務邏輯,自然就不用測試api了比如
user->getuser() 這個method會對應著一個http://domain.com/getuser.xxxx的api
這也是RESTful的由來我的理解,ror裡面的一個method 會自動映射成一個webservice or api,讓人呼叫
最後在強調一遍:不要那麼教條,所有的測驗應該基於這個原則【啥不變測試啥】,如果東西一直在變,你怎麼測