• 软件测试第二次作业


    本次作业链接:https://edu.cnblogs.com/campus/xnsy/2018softwaretest2398/homework/2153

    Gitee项目:https://gitee.com/sebastienf/WordCount

    1、摘要

    本项目的需求可以概括为:对程序设计语言源文件统计字符数、单词数、行数,统计结果以指定格式输出到默认文件中,以及其他扩展功能,并能够快速地处理多个文件。

    可执行程序命名为:wc.exe,该程序处理用户需求的模式为:

    wc.exe [parameter] [input_file_name]

    存储统计结果的文件默认为result.txt,放在与wc.exe相同的目录下。

    2、开发思路

    拿到题目后, 我将这个项目分为了四个部分:基础功能,扩展功能(除递归处理)、递归处理、图形化窗口。

    编码过程中,将大的项目细分为小项目,一个一个小项目分别做实现,然后增量继续开发。在增量过程中,用gitee做版本控制。

    3、完成情况

    本项目中我完成了需求中所要求的所有功能,如下所示

    wc.exe -c file.c     //返回文件 file.c 的字符数

    wc.exe -w file.c     //返回文件 file.c 的单词总数

    wc.exe -l file.c     //返回文件 file.c 的总行数

    wc.exe -o outputFile.txt     //将结果输出到指定文件outputFile.txt

    wc.exe -s            //递归处理目录下符合条件的文件

    wc.exe -a file.c     //返回更复杂的数据(代码行 / 空行 / 注释行)

    wc.exe -e stopList.txt  // 停用词表,统计文件单词总数时,不统计该表中的单词

    [file_name]: 文件或目录名,可以处理一般通配符。

    wc.exe -x  //该参数单独使用,如果命令行有该参数,则程序会显示图形界面,用户可以通过界面选取单个文件,程序就会显示文件的字符数、单词数、行数等全部统计信息。

    4、代码结构

    整个项目我集中在一个Program类、一个负责任务处理的Counter类、一个负责文件递归获取的fileget类、图形化的CountWindows类和一个测试的Test类中。

    其中,各个类中的方法有:

    Program:

    1 [STAThread]
    2         static void Main(string[] args)//主方法,负责程序启动和参数录入。

    Counter:

    /// <summary>
            /// 参数识别
            /// </summary>
            /// <param name="args">控制台参数</param>
            /// <returns></returns>
            public bool selectTask(string[] args)
     
    /// <summary>
            /// 字符计数
            /// </summary>
            /// <param name="file"></param>
            /// <returns></returns>
            public string countLetter(string file)
     
    /// <summary>
            /// 单词计数
            /// </summary>
            /// <param name="file">文件名</param>
            /// <returns></returns>
            public string countWord(string file)
     
    /// <summary>
            /// 行数计数
            /// </summary>
            /// <param name="file">文件名</param>
            /// <returns></returns>
            public string countLine(string file)
     
    /// <summary>
            /// 输出统计结果到result.txt
            /// </summary>
            /// <param name="answer">结果回答</param>
            /// <returns></returns>
            bool outputLine(string answer)
     
     /// <summary>
            /// 输出统计结果到指定文件
            /// </summary>
            /// <param name="answer">结果回答</param>
            /// /// <param name="fileName">指定文件</param>
            /// <returns></returns>
            bool outputLine(string answer,string fileName)
     
    /// <summary>
            /// 返回更复杂的数据(代码行 / 空行 / 注释行)
            /// </summary>
            /// <param name="file">文件名</param>
            /// <returns></returns>
            string countTask(string file)
     
     /// <summary>
            /// 停用词表启用时计数
            /// </summary>
            /// <param name="stoplist">停用词表文件名</param>
            /// <param name="file">被计数文件名</param>
            /// <returns></returns>
            string countWord(string stoplist, string file)
     
    /// <summary>
            /// 启动图形化界面
            /// </summary>
            ///    
        bool countInWindows()

    fileGet:

    /// <summary>
            /// 私有变量
            /// </summary>
            private static List<FileInfo> lst = new List<FileInfo>();
     
    /// <summary>
            /// 获得目录下所有文件或指定文件类型文件(包含所有子文件夹)
            /// </summary>
            /// <param name="path">文件夹路径</param>
            /// <param name="extName">扩展名可以多个 例如 .mp3.wma.rm</param>
            /// <returns>List<FileInfo></returns>
            public static List<FileInfo> getFile(string path, string extName)
     
    /// <summary>
            /// 私有方法,递归获取指定类型文件,包含子文件夹
            /// </summary>
            /// <param name="path"></param>
            /// <param name="extName"></param>
            private static void getdir(string path, string extName)

    CountWindows为IDE生成,省略;

    Test:

    /// <summary>
            /// 测试方法
            /// </summary>
            /// <param name="args">测试输入参数</param>
            /// <returns></returns>
            public bool TestselectTask(string[] args)

     5、算法要点

    这个项目难点在于正确的识别参数和文件的-s处理,也就是递归获取文件;

    对于识别参数,我采用了纯逻辑的方法进行识别处理,在处理时就保证了输入参数的顺序不干扰输出的顺序;

    在实现过程中,一步一步实现,测试完成后再做增量,不影响原本上一个版本的逻辑。

    如下:

    /// <summary>
            /// 参数识别
            /// </summary>
            /// <param name="args">控制台参数</param>
            /// <returns></returns>
            public bool selectTask(string[] args)
            {
                
                bool outPutFlag = false;//特殊输出判断
                string outPutFileName = "";//特殊输出文件名
                string stoplistFileName = "";//特殊输出文件名
                string fileName = "";//文件名
                string result = "";
                List<FileInfo> fileList = FileGet.getFile(".",".c");
                foreach (string item in args)
                {
                    if(item == "-x")
                    {
                        bool re = countInWindows();
                        goto END;
                    }
                }
                foreach (FileInfo file in fileList)
                {
                    if (!(args.Contains<string>("-s")))
                    {
                        foreach (string item in args)
                        {
                            if (item.EndsWith(".c"))
                                fileName = item;
                            else
                                return false;
                        }
                    }
                    else
                    {
                        fileName = file.ToString();
                    }
                    for (int i = 0; i < args.Length; i++)
                    {
                        if (args[i] == "-e")
                        {
                            stoplistFileName = args[i + 1].ToString();
                        }
                    }
                    foreach (string item in args)
                    {
                        if (item == "-c")
                        {
                            result += countLetter(fileName) + "
    ";
                        }
                    }
                    foreach (string item in args)
                    {
                        if (item == "-w")
                        {
                            if (stoplistFileName == "")
                            {
                                result += countWord(fileName) + "
    ";
                            }
                            else
                            {
                                result += countWord(stoplistFileName, fileName) + "
    ";
                            }
                        }
                    }
                    foreach (string item in args)
                    {
                        if (item == "-l")
                        {
                            result += countLine(fileName) + "
    ";
                        }
                    }
                    foreach (string item in args)
                    {
                        if (item == "-a")
                        {
                            result += countTask(fileName) + "
    ";
                        }
                    }
                    if (!(args.Contains<string>("-s")))
                    {
                        break;
                    }
                }
    
                //输出控制
                for (int i = 0; i < args.Length; i++)
                {
                    if (args[i] == "-o")
                    {
                        outPutFlag = true;
                        outPutFileName = args[i + 1].ToString();
                    }
                }
                if (outPutFlag)
                {
                    outputLine(result,outPutFileName);
                }
                else
                {
                    outputLine(result);
                }
                //
                
                END: return true;
            }

    对于文件的递归获取,我通过创建一个可以使用索引访问的强类型列表,然后将文件夹及子文件夹中的文件递归录入,再在参数判断中决定是否使用的办法;

    递归获取过程如下:

    /// <summary>
            /// 私有变量
            /// </summary>
            private static List<FileInfo> lst = new List<FileInfo>();
            /// <summary>
            /// 获得目录下所有文件或指定文件类型文件(包含所有子文件夹)
            /// </summary>
            /// <param name="path">文件夹路径</param>
            /// <param name="extName">扩展名可以多个 例如 .mp3.wma.rm</param>
            /// <returns>List<FileInfo></returns>
            public static List<FileInfo> getFile(string path, string extName)
            {
                getdir(path, extName);
                return lst;
            }
            /// <summary>
            /// 私有方法,递归获取指定类型文件,包含子文件夹
            /// </summary>
            /// <param name="path"></param>
            /// <param name="extName"></param>
            private static void getdir(string path, string extName)
            {
                string[] dir = Directory.GetDirectories(path); //文件夹列表   
                DirectoryInfo fdir = new DirectoryInfo(path);
                FileInfo[] file = fdir.GetFiles();
                //FileInfo[] file = Directory.GetFiles(path); //文件列表   
                if (file.Length != 0 || dir.Length != 0) //当前目录文件或文件夹不为空                   
                {
                    foreach (FileInfo f in file) //显示当前目录所有文件   
                    {
                        if (extName.ToLower().IndexOf(f.Extension.ToLower()) >= 0)
                        {
                            lst.Add(f);
                        }
                    }
                    foreach (string d in dir)
                    {
                        getdir(d, extName);//递归   
                    }
                }
            }

    这里为高风险部分,错误易造成程序崩溃,故在编码过程中进行了多次尝试,甚至做好了备用方法:只搜索文件夹,文件内容重复读取直至为空。

    其他的实现办法均为语言基础,故不赘述。

    在Counter类中,预留了继续发展程序规模的位置,只需要在参数处理参数的方法中添加条件,对应添加相应方法即可。

    6、代码测试

    最后在对程序的测试中,我设计了如下的参数组合作为测试用例,充分考虑了各功能的冲突问题:

    1、-c -w -l test.c -o out.txt 

    2、-l -w -c -s -e stopList.txt -o 1.txt

    3、-x

    4、-a -s -o 1.txt

    5、-o 1.txt

    6、-s

    7、-e test.c -o 1.c

    8、-a -x

    7、学习心得

    这次的项目开发中除了递归算法以外,基本没有遇到太大的困难。此次开发中运用gitee做代码管理,熟悉了gitee的基本特性。这次作业运用新的知识点,将测试结合进自己得到开发过程中,对于软件测试的意义有了大概的理解。大三了,对自己的要求也要更高,对自己代码的要求也是,每一次重构,每一次修复,都是对自己来说的一次进步。

  • 相关阅读:
    html5 桌面提醒:Notifycations
    windows 下 apache 的虚拟主机配置
    javascript 跨域
    javascript 类型数组读取二进制数据
    javascript parseInt() 函数的进制转换陷阱
    javascript 中几个与正则表达式相关的应用
    javascript 中的二进制运算
    一段小代码,发布网页时为js 、css 文件加上版本号
    base64 编码及解码
    PHP 的比较运算与逻辑运算
  • 原文地址:https://www.cnblogs.com/ssfei/p/9696487.html
Copyright © 2020-2023  润新知