PowerShell是一种命令行外壳程序和脚本环境,使命令行用户和脚本编写者可以利用 .NET Framework的强大功能,也可以调用Azure。在Win10里面附带PowerShell V5,PowerShell也能够容易地集成到Jenkins里面。
本文要解决的问题:
数据库部署之后进行冒烟测试,确保相应的对象,比如表,存储过程,视图,具体数据等等已经部署到位,避免到了后续集成测试时与其它错误混杂在一起,减少Root Cause的时间。
解决方案:
1,利用PowerShell里面的Pester测试框架,Pester提供了一个用来在PowerShell内部通过单元测试执行和验证PowerShell命令的框架。Pester遵循一个文件命名规范:命名的测试可以在测试时被自动发现,和一套简单的函数集,Pester相当于是PowerShell的xUnit。
2,用户只需专注在写好SQL语句来校验数据库,注意2个要点:
比如如下
-- check newly deployedSELECT * from sys.all_objects where name = 'td_searchbyname' and create_date > dateadd(MI, -10, getdate());-- check deployed and no current modificationSELECT * from sys.all_objects where name = 'td_searchbyemail' and modify_date < dateadd(MI, -10, getdate());SELECT * FROM TABLE123 WHERE FIELDA = 'EXPECTEDVALUE' AND FIELDB = 'FFFF';-- check output of query procedure is the expected value, with several linescreate table #TempTable1(name VARCHAR(50) PRIMARY KEY, quantity INTEGER)insert into #TempTable1EXEC po_searchbyname 'Mike'SELECT * from #TempTable1 where quantity = 234;
把文件的后缀名设为.sqlt, 余下的执行、报告等等交给PowerShell.
$FileList = Get-ChildItem -Path $SqltPath -Include "*.sqlt" -Recurse
$SqlPath是.sqlt文件的根目录,也可能就是其它Sql文件的根目录,上述语句把全部.sqlt文件找到,放入$FileList当中。
然后,遍历$FileList,根据每个.sqlt文件生成一个Pester的Test Context,如下
foreach ($SqltFile in $FileList) {$SqlList = Get-ZmSqlTestCaseList($SqltFile)Context "File:$($SqltFile.Name)" {It "SQL:" -TestCases $SqlList {$sqlcmd = $sqlConn.CreateCommand()$sqlcmd.CommandText = $Sql$result = $sqlcmd.ExecuteScalar()$result | Should -Not -BeNullOrEmpty}}}
以上核心函数是Get-ZmSqlTestCaseList($SqltFile)
function Get-ZmSqlTestCaseList($SqltFile) {$RawSqlList = Get-Content $SqltFile -Delimiter ";"$SqlList = [System.Collections.ArrayList]::new()foreach ($RawSql in $RawSqlList) {$Sql = ConvertTo-ZmValidSql $RawSqlif ($Sql) {[void]$SqlList.Add(@{Sql = $Sql })}}return $SqlList}
$RawSqlList = Get-Content $SqltFile -Delimiter ";"
根据“;”得到了初步的Sql语句列表,然后进行逐条检查并转换到有效的Sql语句,关键函数是ConvertTo-ZmValidSql
function ConvertTo-ZmValidSql([string]$RawSql) {if ($null -eq $RawSql) {return $null}$Sql = $RawSql.Trim()if ($Sql.Length -lt 8) {return $null}$BatchLineList = $Sql.Split("`n")$NotCommentLineCount = 0foreach ($item in $BatchLineList) {$item = $item.Trim()if ($item.Length -ge 2) {$NotCommentLineCount = $NotCommentLineCount - $item.SubString(0, 2).IndexOf("--")}}if ($NotCommentLineCount -eq 0) {return $null}return $Sql}
以上语句是判断以分号;分割的Sql语句是否有效,略作转换。
以上就是这个小工具的主体,装上数据库链接打开即可运行,完整测试用例代码如下
$FileList = Get-ChildItem -Path $SqltPath -Include "*.sqlt" -RecurseDescribe "DB-Smoke-Testing" {BeforeAll {$SqlConn.Open()}AfterAll {$SqlConn.Close()}foreach ($SqltFile in $FileList) {$SqlList = Get-ZmSqlTestCaseList($SqltFile)Context "File:$($SqltFile.Name)" {It "SQL:" -TestCases $SqlList {$Sqlcmd = $SqlConn.CreateCommand()$Sqlcmd.CommandText = $Sql$result = $Sqlcmd.ExecuteScalar()$result | Should -Not -BeNullOrEmpty}}}}
其中$SqlConn是 System.Data.SqlClient.SqlConnection,在前面初始化。
以上测试运行结果与其它Junit结果一样,可以被Jenkins记录,方便查询。
因此,对于DBO,只需在.sqlt文件当中写好sql查询语句。
----
小结:
本文阐述了一个数据库冒烟测试具体问题,与本公众号过去文章有点不一样,对于绝大多数老读者而言,用不到。因此,最后要传递的信息是值得设法提升测试的便利性,加强持续集成和持续测试。




