posts - 13,  comments - 26,  trackbacks - 5
jquery几个的一些有用的小函数:
有了trim这个函数,遇到空格再也不用自己去实现一遍了
$.trim(str)
jQuery Code
$.trim(" hello, how are you? ");

Result:"hello, how are you?"

还在用冗长的脚本去判断当前的浏览器是什么吗?不用了,使用$.browser
$.browser 返回bool,包含的枚举值有 $.browser.safari, opera, msie, mozilla ,
操作数组的一些函数:

$.each和$().each很像,可以吧$.each()看成静态方法,而$().each则是实例方法,$.each()的用法如下:
 $.each( [0,1,2], function(i, n)
{ alert( 
"Item #" + i + "" + n );});

比较有意思的是下面这种用法:
$.each( { name: "John", lang: "JS" }, function(i, n)
{ alert( 
"Name: " + i + ", Value: " + n );});

能把属性名i和属性值n打印出来,呵呵,多好的一门动态语言

$.grep() 熟悉linux的开发人员肯定喜欢这个函数,很清晰的用法:
$.grep( [0,1,2], function(i){ return i > 0;});


可以吧$.map()和$.each做个比较,map有返回值,map的方向是根据一个数组的值得到另一个数组,而each你return了也不会有什么不同
$.map( [0,1,2], function(i)
return i + 4;});


$.merge()很有用的一个函数,尤其是你在做选择合并的时候
var array = [3,2,1];
$.merge( array, [
4,3,2] )


$.extend()这个函数很想一些语言里的类派生的关键字,也确实可以这么用,把这个函数用于对象复制也很好用:
Query Code
var defaults = { validate: false, limit: 5, name: "foo" };
var options = { validate: true, name: "bar" };
var settings = jQuery.extend({}, defaults, options);
//Result:
settings 
== { validate: true, limit: 5, name: "bar" }

好好使用jquery提供的这些函数,确实能够给我们带来很大的方便,不要光把玩于一些效果类的插件,实用的才是最好的
posted @ 2007-07-03 00:28 sharpedge 阅读(111) | 评论 (0)编辑
方便地查阅jquery的相关函数可以访问http://visualjquery.com/1.1.2.html ,他的分类比较好,如图:


posted @ 2007-07-02 23:29 sharpedge 阅读(57) | 评论 (0)编辑

使用jquery开发也有一段时间了,会了些皮毛。如何在实际工作中代替我们的一些工作,把好的特性用于实践,提高效率呢?今天花些时间把一些东西总结下
主要是比较在传统dom编程和jquery中我们的一些用法,以讨论更好的使用方式


dom中插入一个新的页面元素,我们通常会:
var div = document.createElement("<div>");
div.innerHTML = "hello";
document.body.appendChild(div);
jquery中就不用这么麻烦了
一行代码搞定:
$("<div>hello</div>").appendTo("body")

 

比较基本的也要说下,原来我也疏漏了些:

div.style.display=””;    <==>  $(div).show();

div.style.display=”none”;  <==>  $(div).hide();

div.sn = 1   <==>  $(div). attr(“sn”,1);

div.style.backgroundColor=’red’   <==>  $(div). css( "backgroundColor", "red" );

 

初始化:

document.body.onload = function(){alert(‘welcome’);}; 

<==>

$(function(){alert(‘welcome’);});

或者传统的 $(document).ready(function(){alert(‘welcome’);})

时间仓促,明天好好写

posted @ 2007-06-28 00:54 sharpedge 阅读(82) | 评论 (0)编辑
相比较asp.net中的调试,rails提供的一些特性让我很是喜爱:
ruby script/console
这个脚本可以让应用加载到irb中,方便地测试rails代码,看到这个,我不禁构思起怎么实现个类似的东西给.net用

不需要response.write之类的方法,也不用自己去实现个序列化,rails里可以直接在页面上这样一下,输出标准的html,很是方便
<%=debug(@xxx) %>

posted @ 2007-04-27 10:35 sharpedge 阅读(82) | 评论 (1)编辑
在ruby第二章里面有一段话:
" This is pretty interesting and important, and so if you weren't
paying attention before, you should probably start now."
讲的就是yield这个关键字所传达的东西,这也是ruby比较有特色的一个地方
输入
    def call_block
      puts "Start of method"
      yield
      yield
      puts "End of method"
    end
    call_block { puts "In the block" }
输出:
    Start of method
    In the block
    In the block
    End of method
对这个yield的用法,网上说法不一,有的说是占位符,有的说是"让路",有的说是宏
http://www.javaeye.com/topic/31752
http://axgle.javaeye.com/blog/31018
在我这个.net开发者看来,更愿意把他看成是个方法委托,用.net写,可以写成这样
输入
   delegate outhandler();
  void call_block(outhandler yield)
    {
      Console.WriteLIne("Start of method");
      yield();
      yield();
      Console.WriteLIne("End of method");
    }
   void test(){Console.WriteLine("In the block"); }
   //调用
    call_block(test);
哈哈,上面的代码似乎要比ruby的冗余很多,但是也要严格很多,不知道我这样的分析对不对,不过还是不能完全代替,如果函数中定义一个变量:
    def call_block
      puts "Start of method"
      @count=1
      yield
      yield
      puts "End of method"
    end
    call_block { puts @count=@count+1 }
输出:
    Start of method
    2
    3
    End of method
也就是说这个代理要获得对上下文作用域的访问权,这在.net里恐怕实现不了,这就有点像一个宏了,甚至是代码织入,不过宏好像不能搞方法传递吧。因
此,ruby的yield还是很有特色,看看他使用的一些例子:
输入
    [ 'cat', 'dog', 'horse' ].each {|name| print name, " " }
    5.times { print "*" }
    3.upto(6) {|i| print i }
    ('a'..'e').each {|char| print char }
输出:
    cat dog horse *****3456abcde
嘿嘿,这些实现.net委托都可以搞定,给个函数指针...
posted @ 2007-04-03 01:21 sharpedge 阅读(314) | 评论 (1)编辑

虎狼之侧,岂容酣睡?

若无虎狼,汝将如何?

虎狼再临,尚能战否?

以前在大学,有如虎狼般追求进步的同伴,促使自己也要努力上进,不敢懈怠。工作以后,没有一个朝夕相处的虎狼作伴,危机感不强,以致倦怠,回来也是打游戏,看新闻,对新技术也是浅尝则止,日渐颓废。这样的日子如果继续,我估计真的就泯然众人矣了...

在没有网上的日子里,反倒静下来看了下书,虽然一向对技术内幕之类的书嗤之以鼻,但还是认真地读着<ASP.NET2.0技术内幕>,毕竟,恢复好的学习习惯更重要,书翻译得不好,但写得还是不错的,认真读,动手多实践,还是有所获的。

今天又可以上网了,网络的浩瀚信息又扑面而来,要努力点学习和思考了,对自己要狠一点

虎狼再临,我必斩之

posted @ 2006-09-27 00:12 sharpedge 阅读(85) | 评论 (0)编辑
 

作为软件质量保证的重要一环,测试代码覆盖率是评判单元测试的重要标准。既然已经为你的代码编写了自动回归的单元测试,你当然想知道是不是所有的代码都测到了,完整的测试代码覆盖率可以说是零缺陷软件的决定性因素之一。

说到.net下的代码覆盖统计软件,当属NCover大名鼎鼎了,我们将其和NAant,Nunit一起配合使用,在每日构建和自动化测试领域是非常方便的,正如我前面所说的,对许多程序员而言,还是集成到一起比较方便使用,方便快捷地调用我想要的功能。因此,我将Ncover集成到了我的Nunit中。

由于现在的开发还是基于fw1.1,所以我也只用版本较低的NCover1.3.3,目前使用倒是没发现什么问题。不知道什么原因,在NCover的网站上没有找到1.3版的源代码,我只有反编译一下用,毕竟直接分析和修改源码还是方便很多。在NCover体系内,最重要的组件是Coverlib.dll,他是一个com组件,需要用regsvr32进行注册使用,当然如果你使用安装包,会自动进行安装的。

那么.net部分做了些什么呢?看看我调用Ncover实现功能的代码:

 

ProfilerSettings ps = new ProfilerSettings();

                   ps.CommandLineExe 
= "nunit-console.exe";

                   ps.CommandLineArgs 
= this._testLoader.TestFileName;

                   ps.CoverageFile 
= Path.Combine(new FileInfo(this._testLoader.TestFileName).Directory.FullName,"coverage.xml");

                   ProfilerDriver driver1 
= new ProfilerDriver(ps);

                   driver1.Start();

                   driver1.WaitForExit();

              System.Diagnostics.Process.Start(ps.CoverageFile);


NCover必须要传入一个可执行文件来进行检查哪些代码被调用了,被检查的引用组件必须有pdb调试文件,否则是不分析。在上面的代码中,我传入nunit的控制台程序,让他跑一遍当前的测试dll,然后设置输出文件到被测试的组件的目录下,开启nunit-console进程,待进程结束后,就会有一个converage.xml文件产生,浏览此文件就能看到统计结果。

 

这中间都发生了什么,究竟是谁完成了这一切?.net部分的代码也没什么特别的地方:

public void Start()

        
{

              ProcessStartInfo info1 
= new ProcessStartInfo(this._ps.CommandLineExe, this._ps.CommandLineArgs);

            info1.UseShellExecute 
= false;

            info1.ErrorDialog 
= false;

              info1.CreateNoWindow 
= true;

              info1.RedirectStandardOutput 
= true;

              info1.RedirectStandardInput 
= true;

              info1.RedirectStandardError 
= true;

            
if (this._ps.WorkingDirectory != null)

            
{

                info1.WorkingDirectory 
= this._ps.WorkingDirectory;

            }


            
this.SetEnvironment(info1.EnvironmentVariables);

           
this._proc = Process.Start(info1);

         }



             我对ncover的代码作了些改动,使新进程在后台运行,否则一运行nunit-console就弹出来一个命令行,很是不爽。从上面的代码可以看出系统仅仅设置了下进程初始状态和环境变量,就完成了覆盖统计和xml文件生成。来看看环境变量的配置代码:

 private void SetEnvironment(StringDictionary env)

        
{

            env[
"Cor_Enable_Profiling"= "1";

            env[
"Cor_Profiler"= "CvrLib.CoverageProfiler";

            env[
"CoverageAssemblies"= this._ps.Assemblies;

            env[
"CoverageLog"= this._ps.LogFile;

            env[
"CoverageXml"= this._ps.CoverageFile;

            
if (this._ps.Debug)

            
{

                env[
"CoverageDebug"= "1";

            }


            
if (this._ps.VerboseLog)

            
{

                env[
"CoverageVerbose"= "1";

            }


            
if (this._ps.DisableSetIL)

            
{

                env[
"CoverageDisableSetIL"= "1";

            }


            
if (this._ps.JITLog)

            
{

                env[
"CoverageLogJit"= "1";

            }


            
if (this._ps.NoLog)

            
{

                env[
"CoverageNoLog"= "1";

            }


        }


       
其实这部分代码就是把相关变量存起来,好让真正的负责人-ConverLib.dll来进行处理。ConverLib.dll负责根据环境变量的值来进行代码的跟踪和记录,生成相关的XML文件。为了使xml更可读,需要把一个xsl文件也自动拷过去。

最后,我们在tools菜单上添加一项查看代码覆盖率报表:

posted @ 2006-03-28 21:39 sharpedge 阅读(1822) | 评论 (3)编辑
 

NUnit支持将测试结果保存为xml文件,于是就产生了针对其文件产生报表的一些工具。目前普遍为人所接受的转报表工具是NUnit2Report task,这个开源组件是和NAnt集成的,你要把他跑起来得用NAnt以及相应的配置文件,这种设计的出发点是基于NAnt的自动构建,生成相应的报表。

很多像我一样的windows程序员,习惯了集成,习惯于一个工具撒都搞定,不是很有耐心去配置相应的东西,我们希望我跑完一个测试就可以得到报表,用来分析,存档和共享。既然这样,我们就把NUnit2Report整合到我们的NUnit里去吧^_^ !

感谢开源,很轻松地得到了NUnit2Reportdll,源码和相关文档。一开始,我一看是个dllsdk里又有介绍,就直接拿来用了,由于是为Nant设计的,所以还必须添加nant.core.dll的引用。里面就一个类NUnit2ReportTask,我设置了输入用的NUnit测试结果文件TestResults.xml,就运行Execute,程序报错,说Nant.core里面出错,晕,我又把很多Nant.*文件引用进来,还是报错。

没办法了,我还是直接用源文件吧,看看哪里出错了。由于NP是为Nant设计的,因此NUnit2ReportTask这个类派生于Task,通过覆写成员函数实现自定义操作,我看了些Task类的Excecute方法的源码,发现原先报出的异常应该与Nant里的一些成员变量有关,而且里面只是些异常捕捉和事件处理,没有太特别的地方,于是就把NUnit2ReportTask里面真正工作的ExecuteTask()方法提取出来,作为公共方法进行调用,然后也把初始化方法也在这里面调用,经过几次尝试,终于可以输出报表了!

就这样整合进去也不是很爽,NAnt没什么用还得带着它,于是我又对代码进行了一番改造,去”NAnt”化!把相关的派生和类型都进行了替换,使其与Nant毫无关系^_^。改造后的源码后面会一并放出。

NP改造完成了,就该整合到NUnit中了,我们在NUnitTools菜单下加了一个菜单

 


然后把改造后的
NP源文件放入Nuit.gui的项目中,添加事件处理函数,内部代码如下:

TestResult result = this._testLoader.Results[0];

string fileName = Path.Combine(new FileInfo(this._testLoader.TestFileName).Directory.FullName,"TestResult.xml");              

              XmlResultVisitor resultVisitor 
= new XmlResultVisitor( fileName, result);

              result.Accept(resultVisitor);

              resultVisitor.Write();

              NUnit2Report report 
= new NUnit2Report();

              report.NUnitResultXml 
= fileName;

              report.Todir 
= new FileInfo(this._testLoader.TestFileName).Directory.FullName;

              report.OutFilename 
= string.Format("{0}.html",result.Name); 

              report.HasFormat 
= true;

              report.BuildReport();

          System.Diagnostics.Process.Start(Path.Combine(report.Todir,report.OutFilename));

                      


在上面这段代码中,我们先用nunit自带的功能生成了一个测试结果的xml文件,然后将其作为参数输入NP中,将html报表输出到被测dll的目录下,并以其测试名称命名文件,自动打开此文件。

运行一个测试,点击菜单按钮,浏览器中效果如下:

 


经过努力,
Nunit终于可以自动生成报表了,看到我的Nunit越来越强大,内心真是喜悦啊^_^

在后面的文章中,我会为Nunit添加更加强大的功能。

posted @ 2006-03-26 20:33 sharpedge 阅读(1309) | 评论 (1)编辑

      随着不断地建立TestCase,需要管理的测试方法也越来越多,一打开Nunit,就是一个大大的测试树,对自动化测试而言,也许每个方法的说明并不重要,但有时候想测试某一项功能时,如何准确地找到该方法绝对是件头疼的事。我希望对左边的每个树结点都有相应的方法说明以便于我进行查看和管理。

    先看看源码吧,我使用的是nunit2.2.7 的源码项目,在代码中,当我们单击左边的树结点时,右边会显示对应得类名和方法名,好,找到这段代码:

 

private void testTree_SelectedTestsChanged(object sender, SelectedTestsChangedEventArgs e)

 
{

                   
if (!IsTestRunning) 

                   
{

                        suiteName.Text 
= e.TestName;

                        statusBar.Initialize(e.TestCount, e.TestName );

                   }


              }



suiteName就是STOP按钮旁那个显示类名和方法名的label控件,它被赋予了事件参数里测试对象名,我欣喜地发现SelectedTestsChangedEventArgs居然有一个属性是Descripton,于是我把代码改成这样:

suiteName.Text = e.TestName + e.Description;

如何给Description赋值呢,我开始去找对应的地方,希望找到取方法特性的地方,把DescriptionAttribute的值赋给事件参数。然后发现下面这段代码:

 

private void tests_SelectedTestChanged(UITestNode test)

              
{

                   
if (SelectedTestsChanged != null

                   
{

              SelectedTestsChangedEventArgs args 
= new SelectedTestsChangedEventArgs(test.Name, test.CountTestCases(),test.Description);

                        SelectedTestsChanged(tests, args);

                   }


              }


              看来Description参数是由UITestNode对象传递来的,UITestNode实现了ITest接口,而Description正是其属性之一,经过不断地代码跟踪,我找到了给description属性赋值的地方,可是困惑也就在这里开始了。

    

protected override string GetFixtureDescription( Type fixtureType )

         
{

              
if ( parms.HasTestFixtureType )

              
{

                   Attribute fixtureAttribute 
=

                       Reflect.GetAttribute( fixtureType, parms.TestFixtureType, 
true );

 

                   
// Some of our tests create a fixture without the attribute

                   
if ( fixtureAttribute != null )

                       
return (string)Reflect.GetPropertyValue( 

                            fixtureAttribute, 

                            
"Description",

                            BindingFlags.Public 
| BindingFlags.Instance );

              }


 

              
return null;

         }


        
    TestCase BuildFrom(System.Reflection.MethodInfo method)是类AbstractFixtureBuilder用来根据mehtodinfo构造TestCase对象的,上面代码位于GenericTestFixtureBuilder中,覆写了基类AbstractFixtureBuilderGetFixtureDescription函数以提供真正的实现。这段代码的作用就是利用反射取出自定义特性对象中Description属性,问题好像一下就明朗了,那么只要我这样写应该就可以显示了吧:

[TestFixture(Description="用作简单测试的素材")]

              
public class SimpleTestCase

              
{

                  [TestAttribute(Description
="测试示例方法")]

                  
public void TestSample()

                  
{

                  }


}



可是当我把程序跑起来时,发现不对啊,显示的Description的值根本就不是我在特性里写的内容,于是我花了不少时间进行耐心的跟踪,希望找到原因,每次发现值到最后的那一步就不是我想要的值了,怎么回事呢?无意中,我查了一下事件参数SelectedTestsChangedEventArgs的类,发现其Description属性返回的值居然不是构造函数里的description参数,不是成员变量description的值,居然是testName!

该类的代码如下:

    

public class SelectedTestsChangedEventArgs : EventArgs 

     
{

         
private string testName;

         
private int count;

         
private string description=string.Empty;

 

         
public SelectedTestsChangedEventArgs(string testName, int count) 

         
{

              
this.testName = testName;

              
this.count = count;

              

         }


 

         
public SelectedTestsChangedEventArgs(string testName, int count,string description) 

         
{

              
this.testName = testName;

              
this.count = count;

              
this.description = description;

         }


 

         
public string TestName 

         
{

              
get return testName; }

         }


 

         
public int TestCount 

         
{

              
get return count; }

         }


 

         
public string Description 

         
{

              
get return this.testName; }

         }


}



    原来我是被NUnit给耍了一把,找到问题就好办了,改下Description这个属性:

    

 public string Description 

         
{

              
get return this.description; }

     }


       
    跑下程序,终于显示出我想要的结果,为了显示得好看点,我把原来的label换成了两个TextBox。最后的显示效果如下:

   在后面的文章中,我会对NUnit进行进一步的改造和整合^_^

posted @ 2006-03-25 18:52 sharpedge 阅读(1416) | 评论 (5)编辑

很久以前就买了<microsoft .net remoting>这本书,以前也有努力看过,也许是不够耐心,一直都没有看完,现在有些时间了,争取把这本书读完,彻底搞懂remoting的机制,可以在项目中用到更深层次的东西,也是对自己的一种鞭策吧 ,不然每天都游戏,工作上也学不到太多东西.
    今天把第5章看完了,也算有些收获吧 ,看能不能在项目中用改造代理类的方式实现分布式服务的负载均衡,好好沉淀沉淀.
    AOP在.net平台上的实现都是在remoting架构下的一些应用,都涉及到处理消息链,看项目中能不能用上

posted @ 2006-03-18 14:40 sharpedge 阅读(327) | 评论 (2)编辑
<2008年10月>
2829301234
567891011
12131415161718
19202122232425
2627282930311
2345678

与我联系

搜索

 

常用链接