• Hard Links是文件系统展现一个文件通过不止一次引用在同一卷中的一个单独文件;junction(有被叫作soft link) 能连接位于同一计算机上不同本地卷的目录;Symbolic Links是一个文件系统对象指向另一个文件系统对象,它被设计来辅助迁移和同UNIX操作系统的应用程序兼容性,它从Windows Vista上的NTFS开始可用。

     

    Demystifying the WinSxS directory in Windows-解释了Hard Links导致Windows文件夹过大问题,NTFS Misreports Free Space?提供了可用空间计算不一致的诊断方法。

  • 2008年06月30日

    本月文章收录

    深入探察相等操作符

    [翻译]Web缓存加速指南

    可伸缩性最佳实践:来自eBay的经验

    理解Load Average做好压力测试

    SQL Server Programming Hacks

    3SQL INJECTION攻击检测工具

    MySQL Performance Tools

    Oracle开发专题之:行列转换

    MascaraECMAScript 4转换经典 JavaScript工具

    UTF-8 BOM导致的无法正常模拟Http请求

    OpenJDKSun的开源Java实现

    List of Free Java Decompilers

    SharePoint Web Services入门

    SharePoint文件磁盘存储组件使用指南

    The Best Developer Cheat Sheets Around

    Firefox 3 Memory Benchmarks and Comparison

    Windows Server 2008Vista SP1新特性Windows Error Reporting (WER)-LocalDumps

    How to call C functions from C++ and vice versa?

    Windows自动更新总结

    Web 设计十诫

    《郎咸平:中国面临前所未有的金融与产业战争》

  • 2008年06月17日

    Unix/Linux速查表

    Linux Commands - A practical reference

    Linux-Unix cheat sheets - The ultimate collection

    Unix Toolbox - a collection of Unix/Linux/BSD commands and tasks

    Advanced Bash-Scripting Guide- An in-depth exploration of the art of shell scripting

    Linux BASH command line

  • 原作者:Markus Clermont, John Thomas

    原文第一部分

     

    背景

    通常我们解决测试AJAX应用程序通过过多的大的端到端测试,并且(很有希望地)高单元测试覆盖。这里,我们概要了用这种方法的主要问题并演示一个有效的测试策略为一个基于GWT应用程序的示例,它超过“测试仅通过GUI。”

     

    GUI测试的问题

    一般通过GUI测试:

    l  是昂贵的(需要长时间写测试而且执行是资源密集型)

    l  有限地深入系统

    l  通常仅考虑“恰当路径”

    l  把多个方面化合成单个测试

    l  速度慢且脆弱

    l  需要大量的维护

    l  很难调试

     

    而在单元测试中不面临许多这些问题,它们本身不够主要是因为它们:

    l  较少深入组件间如何相互交互

    l  不提供业务逻辑和系统功能满足需求的信心

     

    解决办法

    虽然没有“一个通适”解决方案,有一些基本原则我们可以使用,以解决web应用程序的测试问题:

    l  投资在集成测试(找出最小的子系统)

    l  关注分离(不做安排通过你正在测试的接口)

    l  单独地测试每个接口(模拟出所有你不在测试的内容)

    l  考虑在生产中的依赖 (找出如何依赖能失败,并测试它)

    l  混合使用策略和工具。没有银弹。

    l  还有不要。。。你不能扔弃你所有的端到端测试

     

    好的测试食谱

    使用上述原则我们可以建立用于测试 Web 应用程序一个食谱。

    1.     探索系统的功能

    2.     确定系统的体系结构

    3.     确定组件间的接口

    4.     确定的依存关系和故障状态

    5.     对每个功能:

    l  确定参加组件

    l  找出潜在的问题

    l  隔离测试问题

    l  创造一个“恰当路径”测试

    后注:测试的价值

    常见由开发人员编写测试时问道的问题,“这真正值得我的时间?”简短的回答是“总是!”。由于修复一个bug比首先预防它更为昂贵,编写好的测试始终值得耗费时间。

     

    虽然有许多不同分类的测试,最常见分类它们的方式是基于它们的大小和它们测试产品的面。每个测试回答有关产品的特定的问题:

    l  单元测试:该方法履行了其制约?

    l  小集成测试:两个类能互相交互?

    l  中等集成测试:类能正确交互它的依赖?是否正确预见和处理错误?所需的函数是否公开APIGUI 上?

    l  子系统测试:两个子系统能互相交互?是否其中一个预期其它所有的错误并相应地处理它们?

    l  系统测试:是否整个系统如预期表现?

     

    记住这个问题,各种级别的测试使我们可以编写更集中和有意义的测试。请记住有效的测试是指那些提供快速和有用的反馈,即快速识别问题和定位该问题的确切位置。

  • 2008年06月12日

    PreCreateWindow

    MFC9.0

    wincore.cpp中实现的函数AfxEndDeferRegisterClass自动预注册3个窗口类,分别为_afxWnd_afxWndOleControl_afxWndControlBar。自MFC 4.0起,类AfxWnd, AfxFrameOrView, AfxMDIFrameAfxControlBar不再预注册,见KB 140596

    BOOL AFXAPI AfxEndDeferRegisterClass(LONG fToRegister)

    {

    ...

          // work to register classes as specified by fToRegister, populate fRegisteredClasses as we go

          if (fToRegister & AFX_WND_REG)

          {

               // Child windows - no brush, no icon, safest default class styles

               wndcls.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;

               wndcls.lpszClassName = _afxWnd;

               if (AfxRegisterClass(&wndcls))

                     fRegisteredClasses |= AFX_WND_REG;

          }

          if (fToRegister & AFX_WNDOLECONTROL_REG)

          {

               // OLE Control windows - use parent DC for speed

               wndcls.style |= CS_PARENTDC | CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;

               wndcls.lpszClassName = _afxWndOleControl;

               if (AfxRegisterClass(&wndcls))

                     fRegisteredClasses |= AFX_WNDOLECONTROL_REG;

          }

          if (fToRegister & AFX_WNDCONTROLBAR_REG)

          {

               // Control bar windows

               wndcls.style = 0;   // control bars don't handle double click

               wndcls.lpszClassName = _afxWndControlBar;

               wndcls.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);

               if (AfxRegisterClass(&wndcls))

                     fRegisteredClasses |= AFX_WNDCONTROLBAR_REG;

          }

          if (fToRegister & AFX_WNDMDIFRAME_REG)

          {

               // MDI Frame window (also used for splitter window)

               wndcls.style = CS_DBLCLKS;

               wndcls.hbrBackground = NULL;

               if (_AfxRegisterWithIcon(&wndcls, _afxWndMDIFrame, AFX_IDI_STD_MDIFRAME))

                     fRegisteredClasses |= AFX_WNDMDIFRAME_REG;

          }

          if (fToRegister & AFX_WNDFRAMEORVIEW_REG)

          {

               // SDI Frame or MDI Child windows or views - normal colors

               wndcls.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;

               wndcls.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);

               if (_AfxRegisterWithIcon(&wndcls, _afxWndFrameOrView, AFX_IDI_STD_FRAME))

                     fRegisteredClasses |= AFX_WNDFRAMEORVIEW_REG;

          }

          if (fToRegister & AFX_WNDCOMMCTLS_REG)

          {

               // this flag is compatible with the old InitCommonControls() API

               init.dwICC = ICC_WIN95_CLASSES;

               fRegisteredClasses |= _AfxInitCommonControls(&init, AFX_WIN95CTLS_MASK);

               fToRegister &= ~AFX_WIN95CTLS_MASK;

          }

          if (fToRegister & AFX_WNDCOMMCTL_UPDOWN_REG)

          {

               init.dwICC = ICC_UPDOWN_CLASS;

               fRegisteredClasses |= _AfxInitCommonControls(&init, AFX_WNDCOMMCTL_UPDOWN_REG);

          }

          if (fToRegister & AFX_WNDCOMMCTL_PAGER_REG)

          {

               init.dwICC = ICC_PAGESCROLLER_CLASS;

               fRegisteredClasses |= _AfxInitCommonControls(&init, AFX_WNDCOMMCTL_PAGER_REG);

          }

    ...

    }

     

    之后进入AfxDeferRegisterClass,再进入实现在MainFrm.cpp中(这是由于CMainFrame中重写了PreCreateWindow)的函数CMainFrame::PreCreateWindow

    BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)

    {

          if( !CFrameWnd::PreCreateWindow(cs) ① )

               return FALSE;

          // TODO: Modify the Window class or styles here by modifying

          //  the CREATESTRUCT cs

     

          return TRUE;

    }

    处调用winfrm.cpp中的函数PreCreateWindow

    BOOL CFrameWnd::PreCreateWindow(CREATESTRUCT& cs)

    {

          if (cs.lpszClass == NULL)

          {

               VERIFY(AfxDeferRegisterClass(AFX_WNDFRAMEORVIEW_REG));

               cs.lpszClass = _afxWndFrameOrView;  // COLOR_WINDOW background

          }

     

          if (cs.style & FWS_ADDTOTITLE)

               cs.style |= FWS_PREFIXTITLE;

     

          cs.dwExStyle |= WS_EX_CLIENTEDGE;

     

          return TRUE;

    }

    其中函数AfxDeferRegisterClass定义在afximpl.h

    #define AfxDeferRegisterClass(fClass) AfxEndDeferRegisterClass(fClass)

    以上完成了注册窗口过程。

     

    再转入实现在winfrm.cpp中的函数CFrameWnd::Create

    BOOL CFrameWnd::Create(LPCTSTR lpszClassName,

          LPCTSTR lpszWindowName,

          DWORD dwStyle,

          const RECT& rect,

          CWnd* pParentWnd,

          LPCTSTR lpszMenuName,

          DWORD dwExStyle,

          CCreateContext* pContext)

    {

          HMENU hMenu = NULL;

          if (lpszMenuName != NULL)

          {

               // load in a menu that will get destroyed when window gets destroyed

          if (!CreateEx(dwExStyle, lpszClassName, lpszWindowName, dwStyle,

               rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top,

               pParentWnd->GetSafeHwnd(), hMenu, (LPVOID)pContext))

          {…}

     

          return TRUE;

    }

    它调用了实现在wincore.cpp中的函数CWnd::CreateEx创建窗口

    BOOL CWnd::CreateEx(DWORD dwExStyle, LPCTSTR lpszClassName,

          LPCTSTR lpszWindowName, DWORD dwStyle,

          int x, int y, int nWidth, int nHeight,

          HWND hWndParent, HMENU nIDorHMenu, LPVOID lpParam)

    {

          if (!PreCreateWindow(cs) ②)

          {

               PostNcDestroy();

               return FALSE;

          }

     

          AfxHookWindowCreate(this);

    }

    处为函数CMainFrame::PreCreateWindow

     

    综上流程,CMainFrame::PreCreateWindow分别在注册和创建窗口时被2次调用。搜寻MFC调用顺序可以调试(Debug)应用程序,把Step Into(F11)Step Over(F10)和断点(Breakpoint)结合使用,效果最佳!

     

    由于定义在afxwin.h中的函数是虚函数

    virtual BOOL PreCreateWindow(CREATESTRUCT& cs);

    因而可以在自己程序定义的CMainFrame中重写(Override)它,在该函数的第一行加入调试(Debug)中的事件纪录,TRACE/TRACE0/TRACE1/TRACE2/TRACE3,非MFC程序则需要用Win32格式化调试输出

    TRACE(L"CMainFrame::PreCreateWindow \n");

    这样就能在调试(Debug)中看到此输出(output)信息,可以看到它输出了两次,这从另一方面再次验证了上述结论,由于C++多态性,派生类中重写虚函数,若对象是派生类则调用派生类的函数。若再在程序的View(如类CxxxViewxxx为项目名)中重写此方法,在该函数的第一行加上

    TRACE(L"CtestView::PreCreateWindow \n");

    可以看到,此输出接在CMainFrame的两次输出后仅输出一次。

     

    最后,类CFormViewCRecordView不调用函数PreCreateWindow,见KB 131989