自动生成测试数据加强版


加强版存储过程

转载请标明出处,引用请保留头注视。第一版链接 :

http://topic.csdn.net/u/20080516/15/3fcf4880-67e9-4a28-844d-05985db51215.html


-------------------------------------------------------------------------------
-- 自动生成测试数据共享加强版
--
-- 基本特性
-- * 表前缀:@表变量、#临时表、$实体表,支持混合多表。
-- * 无表名:@1...@n #1...#n T1...Tn
-- * 无列名:C1...Cn
-- * 少列名:Cm...Cn
-- * 列分隔:空格和TAB键。
-- * 列填充:数据左边对齐原则,数据不足右向填充NULL。
-- * 占位符:分号(;),控制数据位置,左向填充NULL。
-- * 字符集:不考虑UNICODE/NCHAR,网页能够正常显示的应该没问题,网页不能正常显示的,UNICODE也没用。
--
-- 加强特性
-- * 优化数据类型解析,基本上涵盖了所有的原始测试数据形式。
-- * 逗号(,)不再作为列分隔符,添加指定列分隔符控制,具体方法见示例。
-- * 连续(;;)或离散(;)的分号才会被解析为占位符,维持数据中的分号。
--
-- 解析类型
-- * int
-- * bigint
-- * money (New)
-- * numeric
-- * float
-- * datetime
-- * varchar
-- * varbinary (New)
-- * uniqueidentifier (New)
-- * sql_variant
--
-- Limpire(昨夜小楼)
-------------------------------------------------------------------------------
CREATE PROCEDURE CS#
(
  @Input varchar(8000)
)
AS

SET NOCOUNT ON

declare @tid int,@cid int,@pos int,@num int,@p int,@s int,@tb sysname,@spt varchar(20),@inf varchar(2000),@col varchar(4000),@def sysname,@ent varchar(2),@sql varchar(8000)
declare @tables table(id int identity primary key,name sysname)
declare @data table(id int identity primary key,data varchar(8000),fc as nullif(left(nullif(data,''),charindex(' ',nullif(data,''))-1),'null'))
declare @temp table(id int primary key,temp varchar(4000))
declare @code table(id int primary key,code varchar(8000))

--> 格式整理
set @Input=replace(replace(replace(@Input collate Chinese_PRC_CS_AS_KS_WS,' ',' '),char(9),' '),char(13),char(10))
set @Input=char(10)+ltrim(rtrim(@Input))+char(10)
while charindex(char(10)+char(10),@Input)>0 set @Input=replace(@Input,char(10)+char(10),char(10))
set @Input=stuff(@Input,1,1,'')
if @Input not like '[@#$]%' and @Input not like '0[@#$]%' return
set @Input=replace(replace(@Input,'。','.'),'·','.')
select top 94 n=identity(tinyint,33,1) into # from syscolumns
select @Input=replace(@Input collate Chinese_PRC_CS_AS_KS_WS,nchar(n+65248),char(n)) from #
while charindex('  ',@Input)>0 set @Input=replace(@Input,'  ',' ')
set @Input=replace(@Input,char(10)+' ',char(10))
set @Input=replace(@Input,' '+char(10),char(10))
select @ent=char(13)+char(10),@pos=charindex(char(10),@Input)

--> 解析数据
while @Input<>''
  begin
    select @tb=left(@Input,@pos-1),@tid=isnull(@tid,0)+1,@Input=stuff(@Input,1,@pos,''),@pos=charindex(char(10),@Input)
    if @tb like '0%' set @tb=stuff(@tb,1,1,'')
    else select @inf=left(@Input,@pos-1)+' ',@Input=stuff(@Input,1,@pos,''),@pos=charindex(char(10),@Input)
    if @tb like '%/%' select @spt=stuff(@tb,1,charindex('/',@tb),''),@tb=left(@tb,charindex('/',@tb)-1)
    if @tb like '$%' set @tb=stuff(@tb,1,1,'')
    if @tb='' set @tb='T'
    if len(@tb)=1 set @tb=@tb+ltrim(@tid)
    if @tb like '[^@#]%' set @tb='['+@tb+']'
    insert @tables select @tb
    while @pos>0
      begin
        insert @data select left(@Input,@pos-1)+' '
        select @Input=stuff(@Input,1,@pos,''),@pos=charindex(char(10),@Input)
        if @Input like '[@#$]%' or @Input like '0[@#$]%' break
      end
    if @spt is not null
      begin
        set @inf=replace(@inf,@spt,' ')
        while charindex('  ',@inf)>0 set @inf=replace(@inf,'  ',' ')
        update @data set data=replace(data,@spt,' ')
        while exists (select 1 from @data where charindex('  ',data)>0) update @data set data=replace(data,'  ',' ') where charindex('  ',data)>0
      end
    delete @data where data not like '%[^ -]%'
    insert @code select id,null from @data
    while exists (select 1 from @data where data<>'')
      begin
        set @cid=isnull(@cid,0)+1
        insert @temp select id,case when fc not like '%[^;]%' then null else fc end from @data
        update @data set data=case when fc not like '%[^;]%' and len(fc)>1 then stuff(fc,1,1,'')+' ' else '' end+stuff(data,1,charindex(' ',data),'')
        if exists (select 1 from @temp a join @data b on a.id=b.id and temp is not null and fc is not null and isdate(temp)=1 and isdate(fc)=1) and not exists (select 1 from @temp a join @data b on a.id=b.id and temp is not null and fc is not null and isdate(temp+case when fc not like '%[^;]%' then '' else ' '+fc end)=0)
        begin
          update a set temp=temp+case when fc not like '%[^;]%' then '' else ' '+fc end from @temp a join @data b on a.id=b.id where temp is not null and fc is not null
          update @data set data=case when fc not like '%[^;]%' and len(fc)>1 then stuff(fc,1,1,'')+' ' else '' end+stuff(data,1,charindex(' ',data),'')
        end
        select @num=max(datalength(temp)) from @temp where temp is not null
        if @num is null set @def='sql_variant'
        else if not exists (select 1 from @temp where temp is not null and isnumeric(temp)=0)
          begin
            if exists (select 1 from @temp where (len(temp)>1 and temp like '0%' and temp not like '%[^0-9]%') or temp like '%,%') set @def=@num
            else if exists (select 1 from @temp where patindex('%[Ee]%',temp)>0) set @def='float'
            else if exists (select 1 from @temp where len(replace(replace(replace(temp,'+',''),'-',''),'.',''))>@@max_precision) set @def=@num
            else if exists (select 1 from @temp where temp like '%[^0-9.+-]%') set @def='money'
            else if exists (select 1 from @temp where temp like '%.%')
              begin
                select @p=max(len(parsename(n,2))),@s=max(len(parsename(n,1))) from (select n+case when n like '%.' then ' ' when n like '%.%' then '' else '. ' end n from (select replace(replace(temp,'+',''),'-','')n from @temp where temp is not null) a) b
                if @p+@s>@@max_precision set @def='float'
                else set @def='numeric('+ltrim(@p+@s)+','+ltrim(@s)+')'
              end
            else if exists (select 1 from @temp where temp is not null and isdate(temp)=0 or len(temp)<>8)
              begin
                if exists (select 1 from @temp where cast(temp as numeric(38,0)) not between -9223372036854775808 and 9223372036854775807) select @def='numeric('+ltrim(max(len(replace(replace(temp,'+',''),'-',''))))+',0)' from @temp where temp is not null
                else if exists (select 1 from @temp where cast(temp as numeric(38,0)) not between -2147483648 and 2147483647) set @def='bigint'
                else set @def='int'
              end
            else set @def='datetime'
          end
        else if not exists (select 1 from @temp where temp is not null and isdate(temp)=0) set @def='datetime'
        else if not exists (select 1 from @temp where temp not like '0x%' or temp like '0x%[^0-9a-f]%') select @def='varbinary('+ltrim((@num-3)/2+1)+')'
        else if not exists (select 1 from @temp where temp not like replicate('[0-9a-z]',8)+replicate('[-]'+replicate('[0-9a-z]',4),3)+'[-]'+replicate('[0-9a-z]',12)) set @def='uniqueidentifier'
        else set @def=@num
        if isnumeric(@def)=1 set @def='varchar('+@def+')'
        set @col=isnull(@col+',','')+'['+isnull(left(@inf,charindex(' ',@inf)-1),'C'+ltrim(@cid))+'] '+@def
        select @inf=nullif(stuff(@inf,1,charindex(' ',@inf),''),''),@def=left(@def+'(',charindex('(',@def+'(')-1)
        update a set code=isnull(code+',','select ')+case when @def in ('datetime','varchar','uniqueidentifier') then isnull(''''+temp+'''','null') else isnull(temp,'null') end from @code a join @temp b on a.id=b.id
        delete @temp
      end
    if @inf is not null
      begin
        update @code set code=code+replicate(',null',len(@inf)-len(replace(@inf,' ',''))+1)
        set @col=@col+',['+replace(rtrim(@inf),' ','] sql_variant,[')+'] sql_variant'
      end
    select @sql=isnull(@sql+' union all'+@ent,'')+code from @code
    print '--> 测试数据:'+@tb
    print case when @tb like '@%' then 'declare '+@tb+' table' else 'if object_id('''+case when @tb like '#%' then 'tempdb.dbo.' else '' end+@tb+''') is not null drop table '+@tb+@ent+'create table '+@tb end+'('+@col+')'+@ent+'insert '+@tb
    print @sql
    delete @data
    delete @code
    select @cid=null,@spt=null,@inf=null,@col=null,@sql=null
  end

--> 智能代码(略)
select @sql=isnull(@sql+@ent,@ent)+'select * from '+name from @tables
print @sql

SET NOCOUNT OFF

GO

加强版使用示例

--> 多表
exec cs# '@var/,
id data
1, 表变量@
2, 指定逗号为列分隔符
3  空格和TAB是默认列分隔符
#tmp
id data
-- -------
1  临时表#
2  忽略分隔横线
3  默认逗号不是列分隔符:a,b,c,d
$tab
id   data
---- -------
1    实体表$
2    保留null值
null null'
go

--> 无表名/无列名(表前缀@#$前用0修饰)
exec cs# '@
id data
1 无表名
0#tmp
2 无列名
0$
3 双无'
go

--> 动态列名:列名不足动态添加Cm...Cn,数据左边对齐原则。
exec cs# '@dynamic_column_name
a
11 12 13
   21 22
      31'
go

--> 动态填充:数据列不足,右向填充NULL值。
exec cs# '@dynamic_fill_null
a  b  c  d  e
11 12 13
   21 22
      31'
go

--> 占位符:控制数据的位置,左向填充NULL值。
exec cs# '@semicolon
a  b  c  d  e
11 12 13
;  21 22
;  ;  31'
go

--> 占位符增强特性:数据中的分号不会解析为占位符。
exec cs# '@semicolon
a b c d
; ;; 连续;;或离散;才会被解析为占位符'
go

--> 时间解析1
exec cs# '@time
id date boy
1 2001-1-1 Mark
2 20020101 John
3 23:15:39 Paul'
go

--> 时间解析2
exec cs# '@time
id date boy
1 2001-1-1 12:28:47 Mark
2 20020101 17:30:00 John
3 2003/1/1 23:15:39 Paul'
go

--> 基本上可以覆盖所有的原始测试数据形式
exec cs# '0@data_type
001 1,2,3 1.0E10 123456789012345678901234567890123456789 $9.99  9.99 9223372036854775808                    -9223372036854775808 -2147483648 20080101 2008-07-05 23:59:59.000 0x1234 681000D3-0E3A-49ED-8F59-80973A021B8E A
002 4,5,6 2.0E11 111111111111111111111111111111111111111 99.99 99.99 99999999999999999999999999999999999999  9223372036854775807  2147483647 20081231 2008-07-06 00:00:00.000 0xabcd 09E80A5C-7699-4BC9-AEF4-B0BCCF2E03E9 B'
go

/*
PS
表前缀$和美元符号$冲突,如美元货币类型出现在第一列会报错。
$99.9这种原始测试数据形式实属罕见,有需要者自行修改表前缀定义。
*/

Limpire

2008-07-07

  • 0
    点赞
  • 0
    收藏
  • 打赏
    打赏
  • 0
    评论
wings是一款用于单元测试测试用例驱动框架自动生成工具,这款工具主要是全自动生成单元测试驱动代码与测试数据。解决做单元测试耗时耗力,编写难度大等问题。提升开发和测试效率。 特点: (1) 程序参数深度分析问题 Wings通过编译器底层技术,将输入的源文件,按照函数为单位,形成模块对象。对象中包含函数的输入参数,返回值类型等信息,供驱动函数模块和测试用例模块使用。每个文件作为一个单元,针对其中的每个函数的每个参数进行深度解析,对于嵌套类型,复杂类型等都可以实现精确的解析和分解,将复杂类型逐层讲解为基础数据类型,并产生参数结构的描述文件(PSD)。 (2) 函数驱动自动生成模块 依据PSD文件的格式信息,自动生成被测源程序的所有驱动函数,单元测试过程不再依赖开发人员手动编写测试函数,只需将生成的驱动函数和被测源文件一起编译,即可执行测试并查看测试结果。测试驱动自动生成程序基于PSD描述,全自动构建驱动被测程序运行的所有参数,必须的全局变量,并可根据复杂变量的层级结构产生结构化的测试驱动程序,可以节省大量的单元测试用例的编写时间。 (3) 测试数据自动生成与管理 用于自动生成测试数据测试数据与被测函数提取的信息相互对应,数据以一定的层次逻辑关系存储在json文件中。数据和经过分解和展开后的数据类型是一一对应的。这些数据用户可以根据业务要求随意边际,并且用json文件进行结构化,层次化展示,非常的清晰。其中的测试数据包括全局变量值、被测函数调用时的参数值。 优点: 1. 可以为任意复杂参数结构C语言开发的系统全自动生成测试驱动程序 2. 可完成对于被测试函数的参数进行多层编译解析,并完成复杂参数赋值的代码的自动生成。 3. 支持被测函数引用的全局变量的分析和自动赋值程序的生成。 4. 能够区分系统变量和用户变量,对于复杂的系统变量可由用户自定义赋值模板。 例如File类型,而不是把复杂的系统变量全部展开。 5. 支持多层次的可视化的数据表格来对变量进行赋值,而无需关注驱动程序本身。 数据表格可以表达任意深度和多层次的数据关系,用户只需要对表格数据进行编辑,自动生成的驱动程序会自动完成表格数据的读取和参数赋值的构造过程。 6. Wings支持所有C语言的数据类型(基础类型,结构体,指针,数组,枚举等)以及高层级数据结构。 例如链表的分析和对应的驱动和数据表格框架的生成。 7. Wings生成的代码与人工写的非常相近,可读性强,自带注释和按照层次的缩进和代·码编排。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页
评论

打赏作者

Limpire

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值