我正在针对可以针对各种参数值运行的proc编写tsqlt。我最初构建了一个填充假表的proc - 然后根据可能的值进行了1次tsqlt测试(最后进行了35次测试,并且每次都有效)。
我想要做的是将这些减少为1个测试(因为它们都是真正测试相同的功能 - 仅针对不同的值)。我以为我可以用这样的光标做到这一点:
---- Declare Sproc Variables
DECLARE @ReviewId INT;
DECLARE @SourceId INT = 1;
CREATE TABLE #Present
(
SubmissionReviewId INT ,
username VARCHAR(50)
);
CREATE TABLE #Expected
(
SubmissionReviewId INT ,
username VARCHAR(50)
);
--Create Cursor to loop through each active value
DECLARE review_id CURSOR
FOR
SELECT ReviewId
FROM reftype.Rev
WHERE IsActive = 1;
OPEN review_id;
FETCH NEXT FROM review_id
INTO @ReviewId;
WHILE @@FETCH_STATUS = 0
BEGIN
--Setup Fake Data according to the specified test condition
EXEC ut_DataSetupProc @ReviewId = @ReviewId;
-- Run set cutover Sproc
EXEC Procbeing Tested @ReviewId = @ReviewId,
@SourceId = 1, @Username = 'blah';
-- Confirm appropriate review is present in Submission Review Active
DELETE FROM #Present;
DELETE FROM #Expected;
INSERT INTO #Present
SELECT SubmissionReviewId ,
LastModifiedBy
FROM review.SubmissionReviewActive
ORDER BY SubmissionReviewId ,
LastModifiedBy;
/**********************Create table holding expected values***************************/
INSERT INTO #Expected
--This confirms active reviews that belong to other sections/sources remain unaffected
SELECT SubmissionReviewId ,
LastModifiedBy
FROM review.SubmissionReviewActive
WHERE ( ReviewId != @ReviewId )
OR ( SourceId != @SourceId )
UNION
SELECT sra.SubmissionReviewId ,
sra.LastModifiedBy
FROM review.SubmissionReviewActive sra
JOIN review.SubmissionReviewFutureActive srfa ON srfa.IssuerId = sra.IssuerId
AND srfa.ReviewId = sra.ReviewId
AND srfa.Version < sra.Version
WHERE sra.ReviewId = @ReviewId
AND sra.SourceId = @SourceId
UNION
SELECT srfa.SubmissionReviewId ,
'jmarina' AS LastModifiedBy
FROM review.SubmissionReviewFutureActive srfa
JOIN review.SubmissionReviewActive sra ON srfa.IssuerId = sra.IssuerId
AND srfa.ReviewId = sra.ReviewId
AND srfa.Version > sra.Version
WHERE sra.ReviewId = @ReviewId
AND srfa.SourceId = @SourceId
UNION
SELECT srfa.SubmissionReviewId ,
'blah' AS LastModifiedBy
FROM review.SubmissionReviewFutureActive srfa
WHERE srfa.ReviewId = @ReviewId
AND srfa.SourceId = @SourceId
AND srfa.IssuerId NOT IN (
SELECT IssuerId
FROM review.SubmissionReviewActive
WHERE ReviewId = @ReviewId
AND SourceId = @SourceId )
UNION
SELECT sra.SubmissionReviewId ,
sra.LastModifiedBy
FROM review.SubmissionReviewActive sra
WHERE sra.ReviewId = @ReviewId
AND sra.SourceId = @SourceId
AND IssuerId NOT IN (
SELECT IssuerId
FROM review.SubmissionReviewFutureActive
WHERE ReviewId = @ReviewId
AND SourceId = @SourceId )
ORDER BY SubmissionReviewId ,
LastModifiedBy;
/*************************************************************/
EXEC tSQLt.AssertEqualsTable @Expected = '#Expected',
@Actual = '#Present', @Message = N'', -- nvarchar(max)
@FailMsg = N'Active Status is not a match'; -- nvarchar(max)
FETCH NEXT FROM review_id
INTO @ReviewId;
END;
CLOSE review_id;
DEALLOCATE review_id;
DROP TABLE #Expected;
DROP TABLE #Present;
END;
但是,使用
运行此功能EXEC proc name @ReviewId = @ReviewId;
产生一条消息,说明没有运行任何测试。如何起诉光标以减少我的测试次数?或者我应该考虑另一种方法吗?
答案 0 :(得分:2)
我建议你写一些叫做参数化测试的东西。
tSQLt(还)没有原生支持,但有一个简单的解决方法:
您首先要正常编写一个测试。但是,不是硬编码相关的值,而是将它们作为过程的参数。 (对于数据集,您可以使用表参数。)
您还将该程序命名为不以“test”开头的程序(但存在于同一模式中)。
然后根据实际案例编写一个真实的测试,每个测试由一行组成:参数化过程的执行。
这将导致测试比您当前的方法更容易理解。另外,如果其中一个失败,你会立即知道哪个。
作为旁注:您总是希望硬编码您的预期结果。您当前的代码很复杂。您希望最大限度地减少测试本身可能出错的问题。真的,你的目标应该是一目了然的测试。
答案 1 :(得分:0)
最后,我通过几个步骤实现了最终目标: 1.将assert语句移到光标之外 2.创建&#39; cased&#39;带有通过/失败记录的临时表
INSERT INTO #ActualAssert
SELECT p.SubmissionReviewId,e.SubmissionReviewId,
CASE WHEN ( e.SubmissionReviewId IS NULL
OR p.SubmissionReviewId IS NULL
) THEN 'Fail'
ELSE 'Pass'
END
FROM @Present p
LEFT JOIN @Expected e ON e.SubmissionReviewId = p.SubmissionReviewId
UNION
SELECT p.SubmissionReviewId,e.SubmissionReviewId ,
CASE WHEN ( e.SubmissionReviewId IS NULL
OR p.SubmissionReviewId IS NULL
) THEN 'Fail'
ELSE 'Pass'
END
FROM @Present p
RIGHT JOIN @Expected e ON e.SubmissionReviewId = p.SubmissionReviewId;
3。在光标之外我设置了一个新的参数,如果它们存在或者通过了#39;如果他们不是
SET @Result = ( SELECT DISTINCT TOP 1
TestStatus
FROM #ActualAssert
ORDER BY TestStatus ASC
);
4。然后,如果@result不是&#39; Pass&#39;
,我将断言修改为失败EXEC tSQLt.AssertEqualsString @Expected = N'Pass', -- nvarchar(max)
@Actual = @Result, @Message = N''; -- nvarchar(max)
**注意我将之前的当前和预期临时表更改为变量表