用例执行顺序缺陷


Risk_strategy(策略表)中是记录所有的累计策略,其中五个关键字段为main_type, conditions, interval, type,_event,还有一个字段是时长,其中interval字段允许为空,其它均不能为空。

Risk_key(策略KEY)中是记录所有的KEY,根据五个关键字段为main_type, conditions, interval, type,event来生成一个索引ID。其中interval字段允许为空,其它均不能为空。

 背景介绍,新增策略时,根据上述五个关键字来生成一个新的KEY。如果两个累计策略,上述五个关键字相同,但是时长不同,此时会共用相同的KEY。

 策略删除一条记录时,会根据上述五个关键字去搜索策略表,搜索到占用时就不允许删除,而搜索不到时才允许删除。

 删除时查找索引ID的SQL如下:

SQL-1:

 select   ID,STRATEGY_NAME,_MAIN_TYPE,_CYCLE,_CONDITIONS,_EVENT,
           _INTERVAL,_TYPE,_DESCRIPTION,
           _MEMO,_STATUS,GMT_CREATE,GMT_MODIFY,OPERATOR_ID,MODIFY_OPERATOR
           fromrisk__strategy t1 where t1._STATUS = 'U'
           andt1.MAIN_TYPE = #MainType#
           andt1.CONDITIONS = #Conditions#
           andt1.EVENT = #Event#
           andt1.TYPE like CONCAT('%',#Type#,'%')
           <dynamic prepend="and">
              <isNotNullprepend="and" property="Interval">
                  t1.INTERVAL= #Interval#
               </isNotNull>
           </dynamic>

 

SQL-2:

select  ID,STRATEGY_NAME,_MAIN_TYPE,_CYCLE,_CONDITIONS,_EVENT,
           _INTERVAL,_TYPE,_DESCRIPTION,
           _MEMO,_STATUS,GMT_CREATE,GMT_MODIFY,OPERATOR_ID,MODIFY_OPERATOR
           fromrisk_strategy t1 where t1._STATUS = 'U'
           andt1.MAIN_TYPE = #MainType#
           andt1.CONDITIONS = #Conditions#
           andt1.EVENT = #Event#
           andt1.TYPE like CONCAT('%',#Type#,'%')
           and t1.INTERVAL = #Interval#

SQL-3:

 select    ID,STRATEGY_NAME,_MAIN_TYPE,_CYCLE,_CONDITIONS,_EVENT,
           _INTERVAL,_TYPE,_DESCRIPTION,
           _MEMO,_STATUS,GMT_CREATE,GMT_MODIFY,OPERATOR_ID,MODIFY_OPERATOR
           fromrisk_strategy t1 where t1.STATUS = 'U'
           andt1.MAIN_TYPE = #MainType#
           andt1.CONDITIONS = #Conditions#
           andt1.EVENT = #Event#
           andt1.TYPE like CONCAT('%',#Type#,'%')
           <dynamic prepend="and">
              <isNotNullprepend="and" property="Interval">
                  t1.INTERVAL= #Interval#
               </isNotNull>
               <isNull prepend="and" property="Interval">
                  t1.INTERVAL IS NULL
               </isNull>
           </dynamic>


在risk_strategy(策略表)中,有两条策略,策略A与策略B相同,唯一不同的是_interval字段,表示时间段。A策略此处为空,B策略此处为15:00-20:00。

risk__strategy表中记录如下:

策略A:main_type = 11,conditions = 22,_type = 33, event=44,interval 为空,时长为2天。

策略B:main_type = 11,conditions = 22,type = 33, event=44,interval=15:00-20:00,时长为3天。

策略C:main_type = 11, conditions = 22, type = 33, event=44,interval 为空,时长为15天。

 

在risk_key(策略索引ID表)中,有两条索引ID,暂定义为索引A与索引B。

索引A:main_type = 11, conditions = 22, type = 33, event=44,interval 为空。

索引B:main_type = 11, conditions = 22, type = 33, event=44,interval=15:00-20:00。


 其中策略A与策略C同时占用索引A,而策略B占用索引B。

 那么请问先删除A与先删除B会有什么结果不同吗?

 

在SQL-1的情况下,先删除策略A,会去查询索引A有没有被占用,根据SQL-1的结果,自动生成的SQL如下:

select * from  risk__strategy t1
where t1.STATUS = 'U'
and t1.MAIN_TYPE = 11
and t1.CONDITIONS = 22
and t1.EVENT = 44
and t1.TYPE like CONCAT('%',33,'%')


因为INTERVAL字段为空,所以

and t1.INTERVAL = 15:00-20:00

此句SQL未被包含进去。查询出来的结果是策略B也在占用,导致未被使用的索引A未被删除。

实际上索引A应该被删除。

 如果先删除策略B,则索引B会被删除掉,然后再删除策略A,索引A被删除,功能正常。就发现不了上述问题。

 

SQL-2的情况下,先删除策略A,根据SQL-2的结果,自动生成的SQL如下:

select  *  from  risk_strategy t1
where t1.STATUS = 'U'
and t1.MAIN_TYPE = 11
and t1.CONDITIONS = 22
and t1.EVENT = 44
and t1.TYPE like CONCAT('%',33,'%')
and t1.INTERVAL = null


 删除索引A时,根据上述SQL去查询,由于t1.INTERVAL = null永远为假,因此查询出来的结果为始终没有累计策略占用,但是此时另外有一个策略C占用,没有查询不出来。导致不管有没有占用,都会直接被删除。

 如果先删除策略B,那么会直接把索引B删除,再删除策略A时,那么会把索引A删除掉,那么就不会发现这个问题。另外如果此时再删除策略C,那么也能发现这个问题。

 

SQL-3为修复后正确的SQL!

 

上述的问题跟测试用例执行的顺序是有关系的,只有在特定的顺序下才能发现,是偶然的BUG或者几率性的BUG吗?

 

没有偶然的或者几率性的BUG,只是我们没有真正找到他们的规律,这个是个漫长的过程,加油,慢慢寻找BUG的本源。

 

这个BUG算是一个提醒,希望从现在开始,关注到SQL这层。

 

你可能感兴趣的:(用例执行顺序缺陷)