配合NUnit时行单元测试的基类,可以在控制台显示表格

配合NUnit时行单元测试的基类,可以在控制台显示表格 上一篇文章(在这里),总结了和NUnit单元测试工具,其中提到可以把测试类中把信息在控制台输出。不过在NUnit中,只是直接输出文本,想要输出复杂的内容,那就得自己实现了。 我的职业和任务主要就是Web 应用程序,里面有无数次是和数据库打交道的,数据库的话当然就少不了DataTable,如果能在测试的过程中,显示出来DataTable里面的数据,当然再好不过了。 有了这个想法,那就行动吧。 图一 这里面我封装一个基类:class TestBase,它不加[TestFixture]指令,只是准备给其它使用NUnit进行单元测试的类做继承。具体的功能就是封装了两个方法。 1. SayTable(DataTable dt) 在控制台显示表格内的数据,“图一”就是它运行起来的结果 2. Say(string str) 包装了 Console.WriteLine(str) ,这样有了一个比较简洁的方法名称 3. 这个类还有一个属性:public int Length4CutStr 这个属性是控制cell (单元格)内截取文字长度的。默认我设定为25 下面重点介绍一下SayTable这个方法。 这个方法的设计目标是:(一)可以显示表格里面的数据;(二)可以包含字段(列)的名称;(三)自动适应字段(列)内最长的那个cell;(四)使用制表符给表格内容加上边框 前两个目标比较容易实现,只要循环Columns或者Rows就可以完成了。 关键是后面这两个,经过反复研究,也没有找到最完美的办法,也就是始终于法将内容对齐。最开始的时候以为,使用两个空格就能补充一个汉字的位置,用肉眼观察似乎是这样,结果发现,不是那么回事, 最后截图在再放大发现,在NUnit的控制台界面上,英文是7个像素,而中文是13像素。按照中文英文1:2的方式,100个中文和200个英文或者数字,分两行左端对齐,就能看到,英文那一行多出来14个字。换了一种算法,不简单的按照个数,先计算出来空隙,然后再计算字符的数量,这个时候,又出现了小于7像素,不能用英文空格补齐的问题。不过总体来看,大体上还是对齐了,至少对于测试来说,不会让人混淆表格里面的数据。虽然有点勉强,但是基本的目标也已经实现了。 下面给出类的代码: view sourceprint? 001 /// 002 /// 配合NUnit时行单元测试的基类 003 /// 主要的作用是在控制台输出文本或者DataTable里面的内容 004 /// 作者:xpnew.cnblogs.com http://blog.csdn.net/xpnew 005 /// 发布日期:2010年8月11日 006 /// 更新日期:2010年8月11日 007 /// 008 public class TestBase 009 { 010 011 public void Say(string str) 012 { 013 Console.WriteLine(str); 014 } 015 016 private int _Length4CutStr = 25; 017 public int Length4CutStr { get { return _Length4CutStr; } set { _Length4CutStr = value; } } 018 019 //private ArrayList _ColLength; 020 private List _ColLength = new List(); 021 /// 022 /// 在控制台显示DataTable的内容,可以自适应Cell的宽度,但是最多不能超过Length4CutStr属性指定的值 023 /// 024 /// 025 public void SayTable(DataTable dt) 026 { 027 TextCount tc = new TextCount(); 028 //获得列的数量 029 int col_count = dt.Columns.Count; 030 string col_str;//单元格的内容; 031 int field_length = 0; 032 int field_length1 = 0; 033 for (int i = 0; i < col_count; i++) 034 { 035 tc.str = dt.Columns[i].ColumnName; 036 field_length =(tc.ChLength*13+tc.EnLength*7)/13; 037 for (int j = 0; j < dt.Rows.Count; j++) 038 { 039 col_str = dt.Rows[j][i].ToString(); 040 if (dt.Columns[i].DataType == typeof(string) && col_str.Length > Length4CutStr) 041 { 042 col_str = col_str.Substring(0, Length4CutStr); 043 dt.Rows[j][i] = col_str; 044 } 045 046 tc.str = col_str; 047 field_length1 = (tc.ChLength * 13 + tc.EnLength * 7) / 13; 048 field_length = field_length > field_length1 ? field_length : field_length1; 049 } 050 field_length ++; 051 _ColLength.Add(field_length); 052 } 053 char[] line_left = new char[3] { '┏', '┣', '┗' }; 054 char[] line_h = new char[3] { '━', '━', '━' }; 055 char[] line_mid2 = new char[3] { '┳', '╋', '┻' }; 056 char[] line_v = new char[3] { '┃', '┃', '┃' }; 057 char[] line_right = new char[3] { '┓', '┫', '┛' }; 058 059 StringBuilder sb = new StringBuilder(); 060 Say("显示表格数据=========================="); 061 062 //行首: 063 sb.Append(line_left[0]); 064 for (int i = 0; i < col_count; i++) 065 { 066 if (i != 0) 067 sb.Append(line_mid2[0]); 068 for(int j =0 ; j< _ColLength[i]; j++){ 069 sb.Append(line_h[0]); 070 } 071 } 072 sb.Append(line_right[0]); 073 sb.Append('/n'); 074 075 for (int i = 0; i < col_count; i++) 076 { 077 sb.Append(line_v[0]); 078 sb.Append(FillString(dt.Columns[i].ColumnName.Trim(), _ColLength[i])); 079 } 080 sb.Append(line_v[0]); 081 sb.Append('/n'); 082 083 foreach (DataRow row in dt.Rows) 084 { 085 //行间: 086 sb.Append(line_left[1]); 087 for (int i = 0; i < col_count; i++) 088 { 089 if (i != 0) 090 sb.Append(line_mid2[1]); 091 for (int j = 0; j < _ColLength[i]; j++) 092 { 093 sb.Append(line_h[1]); 094 } 095 } 096 sb.Append(line_right[1]); 097 sb.Append('/n'); 098 099 sb.Append(line_v[0]); 100 for (int i = 0; i < dt.Columns.Count; i++) 101 { 102 sb.Append(FillString(row[i].ToString().Trim(), _ColLength[i])); 103 sb.Append(line_v[0]); 104 } 105 sb.Append("/n"); 106 107 108 } 109 110 111 //行尾: 112 sb.Append(line_left[2]); 113 for (int i = 0; i < col_count; i++) 114 { 115 if (i != 0) 116 sb.Append(line_mid2[2]); 117 for (int j = 0; j < _ColLength[i] ; j++) 118 { 119 sb.Append(line_h[2]); 120 } 121 } 122 sb.Append(line_right[2]); 123 sb.Append('/n'); 124 125 126 Console.Write(sb.ToString()); 127 128 } 129 130 private string FillString(string str, int len) 131 { 132 TextCount tc = new TextCount(str); 133 int len1 = tc.ChLength * 13 + tc.EnLength * 7; 134 int len2 = len*13 - len1; 135 136 if (tc.EnLength > 0) 137 { 138 if (len2 > 7) 139 { 140 //len2 = len2 / 7 + (len2 % 7 > 0 ? 1 : 0); 141 str = str + " ".PadRight(len2 / 7, ' '); 142 } 143 int len3 = len2 % 7; 144 if (len3 > 4) 145 { 146 str = str + " "; 147 } 148 } 149 else 150 { 151 if (len2 > 13) 152 { 153 //len2 = len2 / 7 + (len2 % 7 > 0 ? 1 : 0); 154 str = str + " ".PadRight(len2 / 13, ' '); 155 } 156 int len3 = len2 % 13; 157 if (len3 > 7) 158 { 159 str = str + " "; 160 } 161 } 162 return str; 163 } 164 165 } 另外的一个类: TextCount,可以分别统计中英文字符的个数(在当前应用中,这个是主要的作用),也可以统计中文英标点符号的个数。 view sourceprint? 001 /// 002 /// 字符统计的功能 003 /// 004 public class TextCount 005 { 006 private StringBuilder sb; 007 private string _str; 008 public string str { get { return _str; } set { _str = value; Analyze(); } } 009 public TextCount() 010 { 011 012 } 013 public TextCount(string s) 014 { 015 _str = s; 016 Analyze(); 017 } 018 019 private int _len = 0; 020 /// 021 /// 粗略统计,等同于String.Length 022 /// 023 public int len { get { return _str.Length; } } 024 private int _Len = 0; 025 /// 026 /// 精确长度,等同于AllLength 027 /// 028 public int Len { get { return _Len; } } 029 private int _AllLength = 0; 030 /// 031 /// 全部长度 032 /// 033 public int AllLength { get { return _AllLength; } } 034 private int _ChLength = 0; 035 /// 036 /// 中文字数 037 /// 038 public int ChLength { get { return _ChLength; } } 039 private int _EnLength = 0; 040 /// 041 /// 英文字数 042 /// 043 public int EnLength { get { return _EnLength; } } 044 045 046 private int _LetterLength = 0; 047 /// 048 /// 纯字母字数 049 /// 050 public int LetterLength { get { return _LetterLength; } } 051 052 /// 053 /// 英文符号数量 054 /// 055 private int _SymbolLength = 0; 056 public int SymbolLength { get { return _SymbolLength; } } 057 058 private int _ChSymbolLength = 0; 059 /// 060 /// 中文符号字数 061 /// 062 /// 这个只能获取预定义中文符号列表 063 public int ChSymbolLength { get { return _ChSymbolLength; } } 064 065 066 private string _ChSymbilDefine = ",。;“”:?、!《》·「」『』〖〗【】※¥"; 067 068 /// 069 /// 解析字符串,完成统计,每次发第生改变都需要调用 070 /// 071 private void Analyze() 072 { 073 _EnLength = _ChLength = _AllLength = _Len = _LetterLength = _SymbolLength = _ChSymbolLength = 0; 074 075 for (int i = 0; i <_str.Length; i++) 076 { 077 //计算文本长度,区分中英文字符,中文算两个长度,英文算一个长度 078 byte[] byte_len = Encoding.Default.GetBytes(_str.Substring(i, 1)); 079 if (byte_len.Length > 1) 080 { 081 _ChLength++;//如果长度大于1,是中文,占两个字节,+2 082 083 if (_ChSymbilDefine.IndexOf(_str.Substring(i, 1)) >-1) 084 { 085 _ChSymbolLength++; 086 } 087 088 } 089 else 090 { 091 _EnLength++;//如果长度等于1,是英文,占一个字节,+1 092 093 094 /******************************** 095 * 其实可以连数字、空格都给统计出来,但是实际中用处不多 096 * 097

 

http://www.cnblogs.com/xpnew/archive/2010/08/11/1797370.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值