未来已来

发布新日志

  • 什么文件组成了虚拟机(vm) (转)

    2008-09-17 16:41:03

    虚拟机在我们测试项目中经常用来搭建测试环境,所以

    一个虚拟机一般以一系列文件的形式储存在宿主机中,这些文件一般在由Workstation为虚拟机所创建的那个目录中。
    这里列出了这些关键文件的扩展名。在这些例子中,<vmname>表示你的虚拟机名字。
    (举例格式)
    扩展名
    文件名
    描述
    .log 
    <vm name>.log or vmware.log
    这个文件记录了VMware Workstation对虚拟机调节运行的情况。当你碰到问题时,这些文件对我们做出故障诊断非常有用。这个文件和虚拟机的配置文件(.vmx)储存在一个目录里面。
    .nvram 
    <vm name>.nvram or nvram
    这是一个储存虚拟机BIOS状态信息的文件。
    .vmdk 
    <vmname>.vmdk 
    这是一个虚拟磁盘文件,它储存了虚拟机硬盘驱动器里的内容。
    一台虚拟机可以由一个或几个虚拟磁盘文件组成。如果你已经特别指定了虚拟磁盘每2GB为一单独文件的话,虚拟磁盘的大小就决定了虚拟磁盘文件的数量。随着数据写入虚拟磁盘,虚拟磁盘文件将变大,直到这些文件为2GB。(如果你在创建虚拟磁盘时已经把所有的空间都分配了,那么这些文件将在初始时就具有最大尺寸并且不再变大了)。几乎所有的虚拟磁盘文件内容关于虚拟机里的磁盘数据,仅仅一小部分是虚拟机的分区信息。
    如果虚拟机是直接与物理硬盘所连接而不是虚拟磁盘的话,虚拟磁盘文件则保存着虚拟机能够访问的分区信息。
    早期版本的VMware产品用.dsk扩展名来表示虚拟磁盘文件。
    <disk name>-<###>.vmdk 
    这是一个再次命名文件,当虚拟机有一个或多个快照时,就会自动创建它。当虚拟机运行时,这个文件就用来储存对虚拟磁盘作更改的内容。可能这样的文件有多个。虚拟机通过加###这种文件名不重复出现的后缀的命名方式以避免文件重名。
    .vmem 
    <uuid>.vmem 
    虚拟机页面文件,它用来备份客户机保存在宿主机上主内存信息。这个文件只有在虚拟机运行时或崩溃后存在。
    <snapshot name and number> 
    每个虚拟机运行时所建立的快照对应一个.vmem文件,它包含了客户机的驻内存信息,它是快照的一部分。
    .vmsd 
    <vm name>.vmsd 
    这是一个集中储存了快照的相关信息和元数据的文件。在它的目录中,可能其它一些文件只有在虚拟机运行时才存在。(而它不会消失)
    .vmsn 
    <vmname>-Snapshot.vmsn 
    这是一个快照状态信息文件,它记录了你在建立快照时虚拟机的状态信息
    <vmname>-Snapshot<###>.vmsn 
    这也是储存快照状态信息的文件。
    .vmss 
    <vmname>.vmss 
    这是一个储存虚拟机挂起状态信息的文件。一些早期版本的VM产品用.std来表示这个文件。
    .vmtm 
    <vmname>.vmtm 
    这是含有虚拟机组资料的配置文件。
    .vmx 
    <vmname>.vmx 
    这是一个初始的配置文件,它储存着创建虚拟机向导或虚拟机编辑器对虚拟机的一些设置。如果你用的是Linux下的VM虚拟机,这个文件的扩展名将是.cfg。
    .vmxf 
    <vmname>.vmxf 
    这个文件是虚拟机组中补充的配置文件。注意当虚拟机组被移除后,这个文件将保留下来。

    目录中的一些文件仅仅在虚拟机运行时才存在。
  • Rational Robot 头文件和库文件(翻译)

    2008-07-05 13:07:30

     

    Robot头文件和库文件
    头文件
    SQABasic头文件包含一系列的声明,头文件可以应用到
    一. 声明共有或则全局常量,变量和用户定义类型
    二. 声明自定义sub,procedures和function
    头文件中的声明可以应用到任何模块(脚本或者类库文件)。用’$include关键字,放在模块开始的地方-例如:
        ’$include “global.sbh”

    SQABasic头文件类型
    Sqabasic支持两种头文件类型:
    一. 头文件保存在sqabasic路径。不用指定任何路径信息就可以在本工程或者其他工程中应用他们
    二. 工程头文件可以保存在TMS_scrīpt文件夹中。不用指定任何路径信息就可以在同一个工程中处理。

    这两种SQABasic头文件都有同样的扩展名- .sbh

    库文件
    库文件包含一个或者更多供procedure从其它文件调用的sub,procedure和function。
    一. SQABasic库文件(扩展名为.sbl或则.rec)
    注意,.rec文件可以作为脚本文件或者库文件,但是.sbl只能被用作库文件。
    二.动态连接库文件(扩展名.dll)
    下边的表格这几种类库文件不同的总结:

     

    .sbl

    .rec

    .dll

    位置

    SQABasic路径

    当前工程文件中Datastore(文件夹 TMS_scrīpt

    TMS_scrīpt/dll文家夹或则其他位置

    范围

    SQABasic路径中,对所有工程文件都可用

    对同一个工程所有脚本可用

    依靠位置

    验证点

    不支持

    支持标准的robot验证点

    支持自定义验证点


    任何.rec文件都能作为库文件。不管怎样,如果一个.rec文件作为脚本(可以从robot中直接运行或者用callscrīpt命令),他必须有一个main过程。

    在SQABasic库文件中声明过程
    如果在SQABasic过程中有一个自定义的过程,你声明类文件的方法同样适用声明过程。
    下边的例子是在sqabasic库文件中(mylib.sbl)声明一个自定义过程(mysub):
        Declare Sub MySub Basiclib “MyLib”( arg1 as string,arg2 as integer)
    一. 关键字basiclib,表示过程mysub在一个sqabasic库文件中
    二.库文件的名字“mylib”,这里不需要写扩展名(.sbl或者.rec)
    备注:basiclib关键字特指.sbx库文件的声明(和.dll库文件相对),这里不需要也不推荐带有.sbx扩展名的声明。

    什么地方声明SQABasic库文件
    可以在任何位置声明SQABasic库文件
    一. 在脚本或者其他库文件,仅在模块中应用过程
    二.头文件中,用道的模块
    库文件包含不需要指定的例程或者’include头文件

    在dll文件声明过程文件
    如果在dll文件的自定义过程,声明过程同样可以声明dll文件。
    下边是dll文件中(mydll.dll)声明自定义过程(mysub)的例子:
     declare sub mysub lib “mydll”(byval arg1 as string,Byval arg2 as integer)
    一. 声明中加入Lib关键字,表示声明的过程在dll文件中(相对于.sbl或者.rec sqabasic库文件)
    二.库文件名字(mydll),跟随库指定的名称
    三.参数声明通常包括关键字byval(参数声明包括任何关键字)

    如果编译位置在sqabas32路径或在系统路径的库文件(.dll),你不用特别声明路径。如果库文件不再sqabas32或者在系统路径,你需要制定路径,比如
     Declare Sub MySub Lib “E:\MyDll”  (byval arg1 as string,Byval arg2 as integer)

    在什么地方声明dll文件
    你可以声在任何为指声明dll文件:
    1. 脚本或者sqabasic库文件,要用过程的模块
    2. 头文件,任何模块指定的头文件

    SQABasic路径
    Sqabasic路径是robot保存和寻找sbl库文件和头文件的地方,用户在robot中也可以定义。
    一旦你在robot中指定sqabasic路径,这个路径是固定的。不管怎样,robot自动设置sqabasic路径,当下列条件是真的时候:
    i. 仍没有明确在robot中定义sqabasic
    ii. 已经在rational Aministrator建立新的工程和数据仓库
    iii. 打开最近创建的工程和数据仓库

    当上边所有条件为真的时候,robot自动在新工程和数据仓库中设置sqabasic路径到下列位置:
    [NewProject]\[NewDatastore]\DefaultTestscrīptDatastore\TMS_scrīpt\SQABas32

    设置步骤:
    1) 点Tools->General Options
    2) 点Preferences页面
    3) 在SQABasic路径中输入路径
    Rational test早期版本没有提供菜单选项来设置sqabasic路径 – 参阅sqa common directory片断
    指导使用头文件和库文件
    推荐下边使用库文件方法:
    a) 自定义函数或者过程应该使用有同样文件名字的头文件(.sbh)和库文件(.sbl),比如DataFunctions.sbh和DataFunctions.sbl。这个过程和函数在头文件中定义(指定声明头文件)和在库文件中定义。看下边的例子
    b) 分离头文件(参阅常量头文件)用于包含常量,变量和用户定义类型用于脚本或者库文件调用。头文件用同样的文件名字后边附加_x或则_C(附加是早期命名规定)。注意包含常量和变量的头文件必须加入到声明头文件和库文件之前。(DataFunctions.sbh和DataFunctions.sbl),比如’include “DateFunctions_c.sbh”。这样做很容易维护。
    c) 通过分类或者程序把相关的函数放在同一个库里,例如,把所有日期相关的函数放到DataFunctions.sbh/sbl,或者把所有的函数加入为特定程序开发的函数库中(比如AppName.SBH/SBL)
    d) 函数是在库文件中子程序的的首选方式,处分过程的结果对于调用脚本是不相关的。函数应该返回一个值,或者适当的,数据可以通过变量或者数组返回。在后边的例子中,函数返回的结果表示成果或者失败。
    e) 库文件中的所有得函数和子程序必须有“注释“,包含这个过程的目的和用途::
    •目的描述
    •调用陈述 (类似函数声明)
    •参数声明
    •返回值
    •例子
    •可能产生的错误
    •历史修改纪录
    请看下边的例子。
    f) 库文件的注释有合理的解释,通过读注释可以知道过程的逻辑
    g) 如果开发和维护robot库文件是集中管理的方式,那么你可以加入到’$include 所有库文件到global.sbh头文件中,这样做对所有头文件都有用。这可以加入缺省的脚本模板。作为选择,测试人员在每个脚本中可以选择或者包含需要的库文件。
    Rational Robot测试指导
    Paul Downes (Paul_Downes@providian.com)
    Carl Nagle (Carl.Nagle@sas.com)
    7 December 20, 2001
    头文件和库文件的例子
    (NB. 这只是个例子.)
    ___________________ Declarations Header: Excel.sbh ___________________
    '##############################################################################
    '# Excel Function Library v4.0 Library Header File
    '# ===========================
    '#
    '# DEscrīptION:
    '# Contains functions that utilize Excel's COM Automation interface to use
    '# spreadsheets. See Excel.sbl for library details.
    '#
    '# PACKAGE:
    '# Excel.sbh Library Header File
    '# Excel.sbl Source Code and Documentation
    '# Excel_X.sbh Library Include File
    '#
    '# HISTORY:
    '# Orig Author: Andy Tinkham <andy@tinkham.org>
    '# Orig Date : 12-10-98
    '#
    '# Error Handling Code by Mark Butler (MKButler@russell.com) and Andy Tinkham
    '#
    '# CHANGES:
    '# 00/00/00 Author Change details
    '#
    '# COPYRIGHT:
    '# This code is copyright 1998-2002 by Andy Tinkham <andy@tinkham.org>.
    '# except where otherwise indicated. Permission is given for use by the
    '# Rational TeamTest community. Redistribution is allowed as long as no charge
    '# is made for this code and all authorship credits remain intact.
    '##############################################################################
    '# CONSTANTS, VARIABLES, DATATYPES
    '$Include "Excel_X.sbh"
    '# EXPORTED FUNCTIONS
    Declare Function ReadExcelDataSingle BasicLib "excel" (sFileName As String, _
    sCell As String, Optional vSheet As Variant) As String
    Declare Function ReadExcelData BasicLib "excel" (sFileName As String, _
    sData() As String, Optional vSheet As Variant, Optional vRange As _
    Variant, Optional vCell As Variant, Optional vColumnHeaders As Variant) As Integer
    Declare Function WriteExcelDataSingle BasicLib "excel" (sFileName As String, _
    sCell As String, vValue As Variant, Optional vSheet As Variant) As Integer
    Declare Function WriteExcelData BasicLib "excel" (sFileName As String, _
    sCell As String, vValues() As String, Optional vSheet As Variant) As Integer
    Declare Function RetrieveNamedRanges BasicLib "excel" (sFileName As String, _
    sResults() As String, Optional vSkipBuiltIns As Variant) As Integer
    Declare Function VerifyNamedRanges BasicLib "excel" (larstrUsedNames() As String, _
    lstrFileName As String) As Integer
    Declare Sub SortCSVFileInExcel BasicLib "excel" (i_strCSVFile As String, _
    i_strCellToSortBy As String, Optional i_varSecondCellToSortBy As Variant)
    Declare Function GetWorksheets BasicLib "excel" (sFileName As String, _
    sWorksheets() As String) As Integer
    Testing Guidelines Rational Robot
    Paul Downes (Paul_Downes@providian.com)
    Carl Nagle (Carl.Nagle@sas.com)
    8 December 20, 2001
    ___________________ Constants Header: Excel_c.sbh ___________________
    '##############################################################################
    '# Excel.sbl Function Library v4.0 Library Include File
    '# ===============================
    '#
    '# DEscrīptION:
    '# See Excel.sbl for library details.
    '#
    '# PACKAGE:
    '# Excel.sbh Library Header File
    '# Excel.sbl Source Code and Documentation
    '# Excel_X.sbh Library Include File
    '#
    '# HISTORY:
    '# Orig Author: Andy Tinkham <andy@tinkham.org>
    '# Orig Date : 12-10-98
    '#
    '# COPYRIGHT:
    '# This code is copyright 1998-2002 by Andy Tinkham <andy@tinkham.org>.
    '# except where otherwise indicated. Permission is given for use by the
    '# Rational TeamTest community. Redistribution is allowed as long as no charge
    '# is made for this code and all authorship credits remain intact.
    '##############################################################################
    '# LIBRARY CONSTANTS
    Const sqaFailure = -1
    Const FileFormat_Xl7 = &H27
    Const FileFormat_Xl9795 = &H2B
    '# USER-DEFINED TYPES
    '# GLOBAL VARIABLES
    Global objExcel as Object
    Global bPersistExcelObj as Integer
    Testing Guidelines Rational Robot
    Paul Downes (Paul_Downes@providian.com)
    Carl Nagle (Carl.Nagle@sas.com)
    9 December 20, 2001
    _________________________ Library: Excel.sbl _________________________
    '##############################################################################
    '# Excel Function Library v4.0 Library Header File
    '# ===========================
    '#
    '# DEscrīptION:
    '# Contains functions that utilize Excel's COM Automation interface to use
    '# spreadsheets. See Excel.sbl for library details.
    '#
    '# ReadExcelDataSingle Retrieves the value from a single cell
    '# ReadExcelData Retrieves the values from a range of cells
    '# WriteExcelDataSingle Writes a value to a cell on a specified sheet
    '# WriteExcelData Writes array of values to range on specified sheet
    '# RetrieveNamedRanges Return array of named ranges in specified workbook
    '# VerifyNamedRanges Verify named ranges used by a scrīpt are available
    '# SortCSVFileInExcel Open CSV file and sort data by one or two columns
    '# GetWorksheets Retrieve list of worksheets in a specfied workbook
    '#
    '# PACKAGE:
    '# Excel.sbh Library Header File
    '# Excel.sbl Source Code and Documentation
    '# Excel_X.sbh Library Include File
    '#
    '# HISTORY:
    '# Orig Author: Andy Tinkham <andy@tinkham.org>
    '# Orig Date : 12-10-98
    '#
    '# Error Handling Code by Mark Butler (MKButler@russell.com) and Andy Tinkham
    '#
    '# CHANGES:
    '# 04/22/99 Andy Tinkham Added RetrieveNamedRanges
    '# 04/26/99 Andy Tinkham Added VerifyNamedRanges
    '# 10/15/99 Andy Tinkham Added SortCSVFileInExcel
    '# 06/30/01 Paul Downes Added GetWorksheets function
    '# 07/22/01 Paul Downes Added persistent Excel object code
    '#
    '# COPYRIGHT:
    '# This code is copyright 1998-2002 by Andy Tinkham <andy@tinkham.org>.
    '# except where otherwise indicated. Permission is given for use by the
    '# Rational TeamTest community. Redistribution is allowed as long as no charge
    '# is made for this code and all authorship credits remain intact.
    '##############################################################################
    '# Some portions of this code provided by and copyright of:
    '#
    '# Paul Downes, Providian Financial <paul_downes@providian.com>
    '#
    '# OPTIONS
    Option Explicit
    Option Compare Text
    '# CONSTANTS
    Const xlNormal = &HFFFFEFD1
    Const xlLocalSessionChanges = 2
    '# IMPORTED FUNCTIONS
    '$Include "Excel_X.sbh"
    '$Include "SQAutil.sbh"
    '$Include "FileSysUtils.sbh"
    '# EXTERNAL DEPENDENCIES
    Declare Function GetPrivateProfileString Lib "kernel32" Alias "GetPrivateProfileStringA" _
    (ByVal lpApplicationName As String, ByVal lpKeyName As String, ByVal lpDefault As _
    String, ByVal lpReturnedString As String, ByVal nSize As Long, ByVal _
    lpFileName As String) As Long
    Declare Function GetWindowsDirectory Lib "kernel32" Alias "GetWindowsDirectoryA" _
    (ByVal lpBuffer As String, ByVal nSize as Long) As Long
    Testing Guidelines Rational Robot
    Paul Downes (Paul_Downes@providian.com)
    Carl Nagle (Carl.Nagle@sas.com)
    10 December 20, 2001
    '# FORWARD DECLARATONS
    Declare Function GetWorksheets (sFileName As String, sWorksheets() As String) As Integer
    '############################################################################
    '# Function GetWorksheets
    '# =============
    '#
    '# DEscrīptION:
    '# Retrieve a list of the worksheets in a specfied workbook (Excel file).
    '# Returns an array (base = 1) of the worksheet names, and the no. of sheets.
    '#
    '# *** TO-DO: validate file type
    '#
    '# EXAMPLES:
    '# Dim sWorksheets() as String
    '# Dim iWorksheetCount as Integer
    '#
    '# iWorksheetCount = GetWorksheets("C:\Test\MyWorkbook.xls", sWorksheets())
    '#
    '# PARAMETERS:
    '# [In] sFileName Excel workbook file name
    '# [Out] sWorksheets() Array of worksheet names
    '#
    '# RETURNS:
    '# Number of worksheets in the workbook, if successful; else, -1
    '#
    '# ERRORS:
    '# none
    '#
    '# HISTORY:
    '# Orig Author: Paul Downes, Providian Financial (paul_downes@providian.com)
    '# Orig Date : 06/30/01
    '#
    '# Change History:
    '# Date Author Details
    '# -------- ----------- ------------------------
    '# 07/22/01 Paul Downes Added support for persistent Excel object
    '#
    '############################################################################
    Function GetWorksheets (sFileName As String, sWorksheets() As String) As Integer
    Dim Result as Integer
    Etc.

    可用的库文档
    SQAPublisher
    作者 :Carl Nagle
    Carl.Nagle@sas.com
    http://groups.yahoo.com/group/RobotDDEUsers/files/Doc/sqabasic2000/SQAPublisher.htm

    DocRipper
    作者:Teresa Dowd
    teresa_dowd@spectramarketing.com
    http://groups.yahoo.com/group/RationalUsers/files/Misc/DocRipper.zip

    SQA共通目录(7.x到2000)
    Rational/SQA TeamTest v7.x版本, 在Administrator程序中设置公有SQA Robot库文件目录,这些可以被所有仓库和工程使用。V7.X版本,每一个仓库都有分开库目录。Administrator程序很容易设置公有目录。不管怎样,工作区是仓库和公有目录间中设置共享库注册适合的地方,Robot注册关键,设置SQABasic32目录地址,也就是存放公有目录的地方。很简单的方法是创建.REG文件来设置,调用该文件;例子如下:
    ___________________ SetCommonSQADir.reg ___________________
    REGEDIT4
    [HKEY_CURRENT_USER\Software\Rational Software\Rational Test\7\Robot\Robot]
    "SQABasic32 Directory"="\\\\test_dev01\\data\\ratrepo\\sqabas32.common"
    ____________________________________________________________
    同样, "UnSetCommonSQADir.reg"文件可以撤销设置. 推荐用网路路径,这样做要比驱动器映射要好得多。通过这种设置公有或者本地仓库库目录的选择方式是独占形式的。共有目录是适当的环境这样robot库的维护是集中的。个别用户在共享目录中都可以创建任何库文件。
    混合公有和本地库文件的地方,共有目录将不能在注册表中设置。共有目录必须保存在网络共享目录中。建议测试脚本中指定’$Include包含网路路径的库文件。不过用common/sbh头文件对于每个本地库文件目录更加简单,这样做相当于”Global.sbh”头文件的声明方式(请看前面部分的第七点)
    例如,设置如下:
    UNC 库文件目录
    Common \\test_svr\data\sqabas32.common ADO.sbh/sbx(1)
    Excel.sbh/sbx
    Etc.
    Local \\test_svr\data\ratrepo\projname\sqabas32 Common.sbh
    Projname.sbh/sbl
    Etc.
    Rational Robot测试指导
    Paul Downes (Paul_Downes@providian.com)
    Carl Nagle (Carl.Nagle@sas.com)
    13 December 20, 2001
    The "Common.sbh" header would reference the shared library headers using the UNC path:
    ___________________ Common.sbh ___________________
    '$Include "\\test_svr\data\sqabas32.common\ADO.sbh"
    '$Include "\\test_svr\data\sqabas32.common\Excel.sbh
    Etc.
    ___________________________________________________
    共享投文件不许用unc路径指定, 比如:
    _____________________ ADO.sbh _____________________
    Declare Function ReadADOData BasicLib "\\test_svr\data\sqabas32.common\ADO" _
    (i_strConnectStr As String, i_strSQL As String, o_strDBData() As String) _
    As Integer
    Etc.
    ___________________________________________________
    备注:
    (1) 远程库文件(i.e. 不再本地库目录中) 必须经过编译.
    (2) 应用以上方法,当调试共有库例程的时候可能会产生“找不到文件”的错误信息.

     

  • DotNet的调试 三

    2008-07-05 12:20:43

       第一个侦听者把信息写入文本文件中。察看第二个。打开微软控制台在事件视图中浏览应用程序事件日志(这个就是我们在配置文件中指定的)。在这里可以看到我们应用程序的事件信息。更多的可能,在这个列表最上边。如果你双击,可以看到其中的内容。我们发现如下信息:

        图

    是输出信息更加容易阅读:

     

    有时候应用程序很复杂,为了容易理解可以格式化跟踪信息。使输出信息更加漂亮,可以使用缩排,看下面的简单代码:

    public void Callee()

    {

           Trace.WrteLine(“Callee started”);

           ……//Some internal logic

           Trace.WriteLine(“Initializing Buffer”);

           ……//Some extra internal login

           Trace.WriteLine(“Exiting Callee”);

    }

     

    public void Caller()

    {

           Trace.Write(“Caller Called”);

           …..//Some external logic

           Callee();

           …..//Some extral Logic

           Trace.WriteLine(“Initializing Buffer”);

           Trace.Write(“Exiting Caller”);

    }

    输出信息如下:

     Caller called

     Callee stared

     Initializing buffer

     Exiting Callee

     Initializing buffer

     Exiting Caller

     

    如果方法执行前后没有显示信息,我们将被这些拷贝的初始化缓存信息所迷惑。除了信息显示不清楚。为了避免不明确,我们使用Trace类支持的缩进功能。修改的代码,使用缩进:

    public void Callee()

    {

           Trace.indent();

           Trace.WriteLine(“Callee started”);

           …..//some internal logic

           Trace.WriteLine(“Initializing Buffer”);

           ….//Some extra internal logic

           Trace.WriteLine(“Exiting Callee”);

           Trace.Unindent();

    }

     

    public void Caller()

    {

           Trace.Write(“Caller called”);

           ….//Some External Logic

           Callee();

           ….//Some Extra Login

           Trace.WriteLine(“Initiallizing buffer”);

           Trace.Write(“Exiting Caller”);

    }

    输出信息如下:

     

    Caller called

           Callee started

           Initializing buffer

           Exiting Callee

    Initializing buffer

    Exiting Caller

    正如你看到的,callee方法输出缩进,很容易分开不同方法的信息。可以调用IndentUnident方法,达到分离信息的目的。

    在配置文件中修改跟踪配置:

    <configuration>

           <system.diagnostics>

                  <trace indentsize = “3” / >

           </system.diagnostics>

    </configuration>

    ------------------------------------------

    调试

    实际上调试和跟踪用得很普遍。Debug类中的方法有相同的名字的方法,这些方法实现了调试的功能。不同之处是在发布版本配置中是禁止使用的(这意味着不能产生二进制代码调用这些代码)。调试输出也可以在配置文件设置,请看下面:

    <confuration>

           <system.diagnostics>

                  <debug autoflush = “true” indentsize = “7” / >

           </system.diagnostics>

    </confuration>

    备注:调试的声明和语法和跟踪很类似。不同之处,就是把有Trace的地方替换为Debug

     

    设置调试开关

    最后讨论的主题是SwitchSwitch是有一些状态的对象。可以在配置文件或者编程的时候改变状态。Switch让你创建可配置的调试跟踪代码。最好了解Switch的方法是写一个段简单代码,如下:

    using System;

    using System.Diagnostics;

     

    namespace Switching

    {

           class SampleClass

    {

           //Create a Switch. It is initialized by an externally specified value

           static TraceSwitch generalSwitch = new TraceSwitch(“CoolSwitch”, “Global Scope”);

           static public void SampleMethod()

           {

                  //The first message is written if the switch state is set to TraceError

    if(generalSwitch.TraceError)

                         console.WriteLine(“TraceError message”);

                  //The second message is written if the switch state is set to TraceVerbose

                  if (generalSwitch.TraceVerbose)

                         Console.WriteLine(“TraceVerbose message”);

                  //The third message is writeen if the switch state is set to TraceWarning

                  if (generalSwitch.TraceWarning)

                         Console.WriteLine(“TreaceWarning message”);

                  //The fourth message is written if the switch state is set to TraceInfo

                  if(generalSwitch.TraceInfo)

                         Console.WriteLine(“TraceInfo Message”);

           }

           public static void Main(string[] args)

           {

                  //calls the sampleMethod method

                  SampleMethod();

           }

           }

    }

     

    有几个switch类:TraceSwitchBooleanSwitch。这个例子中我们用使用TraceSwitch依照他们的状态创建输出信息。Switch状态由TraceErrror,TraceInfo,TraceVerboseTraceWarning属性检查。这些属性检查switch状态和如果trace级别等于或大于相应的常量,那么将返回true。例如,当这个级别是2或者更大那么TraceWarningtrue,下面表格是返回值:

    TraceErroe

    1

    TraceWarning

    2

    TraceInfo

    3

    TraceVerbose

    4

    但是,正如我们已经说的,switch的状态可以在代码中修改,做个修改代码的范例:

    using System;

    using System.Diagnostics;

     

    namespace Switching

    {

           class SampleClass

    {

           //Create a Switch. It is initialized by an externally specified value

           static TraceSwitch generalSwitch = new TraceSwitch(“CoolSwitch”, “Global Scope”);

           static public void SampleMethod()

           {

                  //The first message is written if the switch state is set to TraceError

    if(generalSwitch.TraceError)

                         console.WriteLine(“TraceError message”);

                  //The second message is written if the switch state is set to TraceVerbose

                  if (generalSwitch.TraceVerbose)

                         Console.WriteLine(“TraceVerbose message”);

                  //The third message is writeen if the switch state is set to TraceWarning

                  if (generalSwitch.TraceWarning)

                         Console.WriteLine(“TreaceWarning message”);

                  //The fourth message is written if the switch state is set to TraceInfo

                  if(generalSwitch.TraceInfo)

                         Console.WriteLine(“TraceInfo Message”);

           }

    public static void Main(string[] args)

    {

           Console.WriteLine(“Before manual level set\n”);

           SampleMethod();

           GeneralSwitch.Level = TraceLevel.Warning;

           SampleMethod();

    }

    }

    运行程序,包含以下信息:

     

    Before manual level set

     

    TraceError Message

    TraceWarning message

    TraceInfo message

     

    After manual level set

     

    TraceError Message

    TraceWarning Message

     

    这些展示了改变trace switch层次。

     

    计算性能

    这部分我们将告诉你调试的花费时间。事实上,调试对于商业逻辑不起作用。但是调试代码需要花费时间。我们将计算应用程序中输出信息的花费时间。当你测试一个是建要求严格的应用程序时间,测量就很重要。看下面的代码:

    using system;

    using system.Diagnostics;

     

    namespace DebugDemo

    {

           class PrimeNumberDetector

           {

                  public static bool IsPrime(int n)

                  {

                         int upperbound = (int)Math.Sqrt(n);

                         for (int I = 2; I <= upperbound; I++)

                         {

                                Debug.WriteLine(“Processing number” + n + “, Testing with “ + i);

                                If((n%i) == 0)

                                {

                                       Debug.WriteLine(“FAILED”);

                                       Return false;

                                }

                         }

                  }

                 

                  public Application

                  {

                         [STAThread]

                         static void Main(string[] args)

                         {

                                for(int i = 2; i < 10000;i++)

                                 if (PrimeNumberDetector.IsPrime(i))

                                       Console.WriteLine(“{0} is prime number” , i);

                         }

                  }

           }

    程序测试21000个整数和输出素数。调试的目的是测试每一个输出数字,不管是否是素数。如果数字不是素数,那么输出failed.

    对比测量下带调试和不带调试的时间:

    可以看出调试是昂贵的例子中花费了64%的执行时间

     表

     

    结论:

    文章中描述了调试跟踪.net程序的一般方法。当然还有一些其他问题,如,条件编译我们没有做。想学到更多的东西,可以看msdn。我们希望这篇文章帮助你掌握调试跟踪.net程序的技术。

     

  • DotNet的调试 二

    2008-07-05 12:16:53

       

    事实上,当检查重要条件,比如数据正确性等情况的时候才用这种方法。下边是他最常用的例子:public void StoreObject(PersistentObject obj)

    {

           Trace.Assert(obj != null, "Cannot store null object);

    }

    这个方法检查object对象不是null的时候被存储。当程序失败的时候是产生异常的最好时间,但这不是必要条件。例如,如果这个方法保存了一些重要的程序数据,断言是完美的选择。

    备注:调试跟踪是有用的,如果最终发行版本中包含了断言信息对用户来说是无法忍受的。下面的窍门可以帮助你控制跟踪开关。

     

    如果你手工编译工程(比如命令行编译),缺省显示跟踪信息。如果在c#中用跟踪功能,当你编译代码的时候,要加/d:Trace标志来编译命令行,或者你可以简单的加入#define Trace到文件最顶端。

    比如,下面的小程序:

    using system;

    using System.Diagnostics;

    namespace TraceShow

    {

           class calss1

    {

           ///<summary>

           ///The main entry point for the application

           ///</summary>

           [STAThread]

           static void Main(string[] args)

           {

                  Trace.Listeners.Add(new TextWriterTraceLister(Console.Out));

                  Trace.Write(“Hey,this is a trace message\n”, “SIMPLE MESSAGE”);

           }

    }

    }

    如果在命令行编译,你将看不到任何信息,除非你加上/d:Trace或者加入#define Trace到文件顶部。

    当你在visual c#中编译程序这种情形将改变,visual c#中默认是可用的,结论是你将看到跟踪信息。关闭调试功能,浏览工程属性(可以在解决方案浏览器重或者view->property菜单项。在这个属性页面对话框中,发现条件编译常量(在configuration properties文件夹下,build pane中这个选项是锁定状态),去掉Trace选项):

       图

    public static void Fail(string)

    public static void Fail(string, string)

    Fail方法产生一个无条件断言。它的有些行为有点像Assert方法,但是他不需要任何处理条件。

    带有简单条件的失败条件不能被选中那么用这个方法。下边的例子是这种异常的处理情形:

    try

    {

             throw new Exception(“Sample Exception”);

    }

    catch(Exception Ex)

    {

             Trace.Fail(“Exception caught”, Ex.Message);

    }

     

    pubic static void Write(object)

    public static void Write(string)

    public static void Write(object, string)

    public static void Write(string,string)

     

    Trace类可以在不产生任何条件的情况下写入跟踪信息。比如信息输出到作为跟踪信息的接收者的设备中。用write方法执行输出。

    Write方法可以建立作为对象或者字符串的描绘信息。以前的案例中,object.ToString被呼叫执行。有其他三个方法可以执行类似的行为:writeline输出行,writeif-条件信息,writelineif输出一行条件信息。

    Write方法的第二个参数指定将要写入信息前的分类(比如 一个字符串)

    输出被注册为侦听器。侦听器是可以输出跟踪信息到一些设备的对象。注意AssertFail方法经常输出错误信息到窗体或者控制台,不管那个侦听器被选中。这类对象必须继承TraceListener类,他有以下重要的方法:

    public virtual void Fail(string)

    public virtual void Fail(string,string)

     

    public virtual void Flush(string)

     

    public virtual void Write(object)

    public abstract void Write(string)

    public virtual void Write(object,string)

    public virtual void Write(string,string)

     

    public virtual void WriteLine(object)

    public Virtual void WriteLine(string)

    public virtual void writeLine(object,string)

    public virtual void WriteLine(string,string)

    --------------------------------------------------------------------------------------------

    Fail方法不能阻止应用程序运行,他们仅仅输出错误信息。WriteWriteLine方法写入一个消息。他们不同之处仅仅在于后者输出执行后再输出一行。最后,Flush方法刷新缓存。Flush方法对跟踪信息输出的设备有作用(例如,流)。你可以使用自动刷新每个信息后都自动刷新侦听者。可以在配置文件里面配置:

    <configuration>

            <stream.diagnostics>

                       <trace autoflush = “false” />

             </stream.diagnostics>

    </configuration>

     

    正如你看到的,如果你创建自己的倾听者,需要至少实现write(string)writeline(string)方法(这些方法是抽象方法)。

    微软提供三种跟踪侦听者:DefaultTraceListener,EventLogTraceListenerTextWriteTraceLister.。第一个侦听者有缺省的方法(如果应用程序在命令行的环境下运行,那么输出信息到控制台。如果应用程序在调试情况下,输出到窗口)。第二个侦听者输出信息到指定事件日志中(基于nt技术—winnt,2k,xp或者.net)。第三个倾听者输出文本到流中。

    活动倾听者列表可以在编程中设置或者在配置文件中。缺省包括DefaultTraceListener.

    编程改变活动倾听者列表,要管理倾听者集合(通过添加和删除方法)。配置文件中管理倾听者,你要用下边的语法:

    <configuration>

    <system.diagnostics>

             <trace autoflust=”false”  indentsize = 4>

                       <listeners>

    <add name=”myListener” type=”System.Dianostics.TextWriterTraceListener, system”

    initializeData = “c:\MyListener.log”/>

    <remove type = “System.Diagnostics.DefaultTraceListener,System”/>

    </listeners>

    </trace>

    </system.dianostics>

    </configuration>

    InitializeDat参数是传递到构造器的的字符串参数(指定EventLogTraceListener侦听者事件日志)。

    侦听者很熟悉创建应用程序使用侦听者输出跟踪信息。代码很简单:

    //Trace listeners demo

    //

    //purpose:To demonstrate how to use listeners

    using System;

    using System.Diagnostics;

     

    namespace Assertion

    {

             class Application

             {

                       [STAThread]

                       static void Main(string[] args)

                       {

                                Trace.WriteLine(“Calling WriteLine method”, “Trace Listeners demo”);

                                Trace.Flush();

                       }

             }

    }

     

    这些代码还不够,我们必须创建一个配置文件来设置侦听者:

    <configuration>

    <system.diagnostics>

       <trace autoflush="false" indentsize="4">

    <listeners>

         <remove type="System.Diagnostics.DefaultTraceListener"/>

         <add name="myListener" type="System.Diagnostics.TextWriterTraceListener"

               initializeData="myListener.log" />

        <add name="myListenerEventLog" type="System.Diagnostics.EventLogTraceListener"

              initializeData="Application" />

    </listeners>

       </trace>

    </system.diagnostics>

    </configuration>

    这个配置文件删除了缺省侦听者加入两个自定义侦听者:第一个输出信息到文本文件,第二个输出到事件日志中。对于第一个侦听者initializeData属性指定输出数据的文件,第二侦听者记录事件到事件日志。

    运行程序。检查第一个侦听者,可以看到myListener.log文件,它包含以下信息:Tracing listeners Demo:Calling WriteLine Method

  • DotNet的调试 一

    2008-07-05 12:13:07

          这是很久以前的一篇翻译文章。

          

           Debug是整个软件开发过程中最痛苦的部分之一。我们不想说发现一个小bug是多么的困难-你可能已经都知道。软件中bug的数量是随着软件的复杂程度和经常没有及时修正bug而增长的。这些bug和软件的负责程度互相影响,使工程变得更加复杂。所以我们不断的监控和修改bug

    最好的办法是执行单元测试的时候来修正bug,当软件出现问题的时候,软件不会告诉我们哪里出现错误,为什么出现错误,我们的任务就是跟踪进程去解决他们。

    这篇文章我们就是想告诉你怎样利用DotNet FrameWork来调试和跟踪让这个处理过程变得简单。我们将简要的告诉你怎么样有效的使用他们,并用结合例子说明。

    跟踪

    在这篇文章中首先要讨论的调试的策略是跟踪。跟踪是很强大的技术,因为他允许你看到应用程序的整个在运行期的整个行为,分析他是最有效的,尽管他不能提供需要的信息。

    DotNetSystem.Diagnostics名字空间中提供了跟踪的功能,正确的说是Trace Class

    Trace是个静态类(这意味着所有的成员是静态的,你不需要初始化他来获得它的功能)

    .产生一个断言(有条件或没有)

    .根据提供的条件输出跟踪信息

    .格式化跟踪输出信息

    让我们从简要的成员方法开始研究:

    public static void Assert(bool)

    public static void Assert(bool,string)

    public static void Assert(bool,string,string)

     

    Assert方法显示一个失败信息(应用程序失败的时候显示信息,允许用户中断执行,忽略错误或者重新运行引起错误的代码),如果条件是false,两个重载函数允许显示指定的自定义一个或两个跟着的信息。(这些信息通过string参数设置,这么做允许开发者显示额外的断言失败的信息)

    //Asertion Demo

    //

    //Purpose: To Demonstrate Results of Different Assert Method Calls

    using  System;

    using  System.Diagnostics

    namespace Assertion

    {

             class Application

    {

             [STAThread]

             static void Main(string[] args)

             {

                       //Simple assertion. No additional message

                      Trace.Assert(false);

             }

    }

    }

    程序将显示下面的消息对话框:

    正如你看到的,仅仅是显示异常信息。没有显示任何上下文信息,所以我们不能看到失败的原因。下面,应用程序调用Assert方法用它的一个属性:

    //Asertion Demo

    //

    //Purpose: To Demonstrate Results of Different Assert Method Calls

    using  System;

    using  System.Diagnostics

    namespace Assertion

    {

             class Application

    {

             [STAThread]

             static void Main(string[] args)

             {

                       //Simple assertion. No additional message

                      Trace.Assert(false,”Simple assertion Message”);

             }

    }

    }

    这个程序显示了一个更多信息的对话框。可以看到我们能提供的关于失败原因的信息。

    调用有两个信息的Assert方法,组成更加详细的断言:

    //Asertion Demo

    //

    //Purpose: To Demonstrate Results of Different Assert Method Calls

    using  System;

    using  System.Diagnostics

    namespace Assertion

    {

             class Application

    {

             [STAThread]

             static void Main(string[] args)

             {

                       //Simple assertion. No additional message

                      Trace.Assert(false,”Simple assertion Message””This message just an example.In real application you can provite detailed information here’);

             }

    }

    }

    你现在看到更加详细的信息:

     

Open Toolbar