Gtest框架進行Windows API測試:CreateFile和枚舉文件

前期準備:
測試之前需要下載gtest
我用的是gtest1.7.0 鏈接: https://pan.baidu.com/s/1jHEyazk 密碼: cbvg

如果從官網下載gtest,需要多一步自己編譯gtest/msvc下的VC工程文件gtest.sln。

建立測試工程,將gtest/include添加到頭文件路徑中;將gtestd.lib或者gtest.lib添加到包含庫中。

開始測試:
我先對CreateFile進行了簡單的測試:
因爲我需要對C盤和掛載盤進行測試對比,所以一開始定義了兩個盤符變量。

#include "stdafx.h"
#include <gtest/gtest.h>
#include <string>
#include <afx.h>

char test_0[] = "A:/";
char test_c_0[] = "C:/";
class CreateTest : public::testing::TestWithParam<::testing::tuple<DWORD, DWORD, DWORD>> {};

TEST_P(CreateTest, HandleTrueReturn1) {     //CREATE_NEW 文件不存在時 
    //獲取CreateFile各種參數的組合情況
    DWORD n1 = ::testing::get<0>(GetParam());
    DWORD n2 = ::testing::get<1>(GetParam());
    DWORD n3 = ::testing::get<2>(GetParam());
    //路徑拼接+字符串類型變換
    char test_path_c[100];
    strcpy_s(test_path_c, test_c_0);
    strcat_s(test_path_c, "1.txt");
    CString cstr_c = test_path_c;
    LPCTSTR path_c = (LPCTSTR)cstr_c;
    HANDLE fFile01_c = (HANDLE)CreateFile(path_c, n1, n2, NULL, CREATE_NEW, n3, NULL);
    DWORD lss = GetLastError();
    CloseHandle(fFile01_c);
    DeleteFile(path_c);

    char test_path[100];
    strcpy_s(test_path, test_0);
    strcat_s(test_path, "1.txt");
    CString cstr = test_path;
    LPCTSTR path = (LPCTSTR)cstr;
    HANDLE fFile01 = (HANDLE)CreateFile(path, n1, n2, NULL, CREATE_NEW, n3, NULL);
    DWORD lss2 = GetLastError();
    CloseHandle(fFile01);
    DeleteFile(path);
    EXPECT_EQ(lss, lss2);
}


TEST_P(CreateTest, HandleTrueReturn2) {     //CREATE_NEW 文件存在時 

    DWORD n1 = ::testing::get<0>(GetParam());
    DWORD n2 = ::testing::get<1>(GetParam());
    DWORD n3 = ::testing::get<2>(GetParam());

    char test_path_c[100];
    strcpy_s(test_path_c, test_c_0);
    strcat_s(test_path_c, "2.txt");
    CString cstr_c = test_path_c;
    LPCTSTR path_c = (LPCTSTR)cstr_c;
    HANDLE fFile01_c = (HANDLE)CreateFile(path_c, n1, n2, NULL, CREATE_NEW, n3, NULL);          
    CloseHandle(fFile01_c);
    HANDLE fFile1_c = (HANDLE)CreateFile(path_c, n1, n2, NULL, CREATE_NEW, n3, NULL);
    DWORD lss = GetLastError();
    CloseHandle(fFile1_c);
    DeleteFile(path_c);

    char test_path[100];
    strcpy_s(test_path, test_0);
    strcat_s(test_path, "2.txt");
    CString cstr = test_path;
    LPCTSTR path = (LPCTSTR)cstr;
    HANDLE fFile01 = (HANDLE)CreateFile(path, n1, n2, NULL, CREATE_NEW, n3, NULL);
    CloseHandle(fFile01);
    HANDLE fFile1 = (HANDLE)CreateFile(path, n1, n2, NULL, CREATE_NEW, n3, NULL);
    DWORD lss2 = GetLastError();
    CloseHandle(fFile1);
    DeleteFile(path);
    EXPECT_EQ(lss, lss2);
}

DWORD A_0[4] = { GENERIC_WRITE ,GENERIC_READ,0,GENERIC_READ | GENERIC_WRITE };
DWORD B_0[4] = { 0,FILE_SHARE_DELETE,FILE_SHARE_READ,FILE_SHARE_WRITE };
DWORD D_0[4] = {FILE_ATTRIBUTE_ENCRYPTED,FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_NORMAL,FILE_ATTRIBUTE_READONLY};

//gtest框裏的combine函數可以將給定值進行排列組合
INSTANTIATE_TEST_CASE_P(Return, CreateTest, testing::Combine(testing::Values(A_0[0],
    A_0[1], A_0[2], A_0[3]), testing::Values(B_0[0], B_0[1], B_0[2], B_0[3]),
    testing::Values(D_0[0], D_0[1], D_0[2])
));

int main(int argc, _TCHAR* argv[]) {
    testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}

接下來是枚舉文件的測試,同樣是C盤與掛載盤:

#include "stdafx.h" 
#include <gtest/gtest.h>
#include <iostream>  
#include <string.h>  
#include <Strsafe.h> 
#include <afx.h>
using namespace std;

char test_7[] = "A:/";
char test_c_7[] = "C:/";

class EnumFileTest : public::testing::TestWithParam<int> {

};
DWORD TraverseDirectory(wchar_t Dir[MAX_PATH], char flag)   //傳入路徑 
{
    WIN32_FIND_DATA FindFileData;
    HANDLE hFind = INVALID_HANDLE_VALUE;
    //定義要遍歷的文件夾的目錄
    wchar_t DirSpec[MAX_PATH];
    //  DWORD dwError;
    StringCchCopy(DirSpec, MAX_PATH, Dir);
    //定義要遍歷的文件夾的完整路徑\* 
    StringCchCat(DirSpec, MAX_PATH, TEXT("\\*"));
    //找到文件夾中的第一個文件
    hFind = FindFirstFile(DirSpec, &FindFileData);
    DWORD lss = GetLastError();
    //如果hFind句柄創建失敗,輸出錯誤信息
    if (hFind == INVALID_HANDLE_VALUE)
    {
        FindClose(hFind);
        return lss;
    }
    else
    {
        //當文件或者文件夾存在時
        while (FindNextFile(hFind, &FindFileData) != 0)
        {
            //判斷是文件夾&&表示爲"."||表示爲".."
            if ((FindFileData.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) != 0 &&
                wcscmp(FindFileData.cFileName, L".") == 0 ||
                wcscmp(FindFileData.cFileName, L"..") == 0)
            {
                continue;
            }
            //判斷如果是文件夾
            if ((FindFileData.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) != 0)
            {
                wchar_t DirAdd[MAX_PATH];
                StringCchCopy(DirAdd, MAX_PATH, Dir);
                StringCchCat(DirAdd, MAX_PATH, TEXT("\\"));
                //拼接得到此文件夾的完整路徑
                StringCchCat(DirAdd, MAX_PATH, FindFileData.cFileName);
                //遞歸調用
                TraverseDirectory(DirAdd, flag);
            }
            //如果不是文件夾的情況
            if ((FindFileData.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) == 0)
            {
                //輸出完整路徑
                wcout << Dir << "\\" << FindFileData.cFileName << endl;
                if (flag == 'A') {
                    wchar_t Dir0[MAX_PATH];
                    char test_path_c[MAX_PATH];
                    test_path_c[0] = 'C';
                    for (int i = 1; i < MAX_PATH; i++)
                    {
                        test_path_c[i] = Dir[i];
                    }

                    strcat_s(test_path_c, "\\");
                    char file_na[256];
                    int iLength = WideCharToMultiByte(CP_ACP, 0, FindFileData.cFileName, -1,
                        NULL, 0, NULL, NULL);
                    //將tchar值賦給_char    
                    WideCharToMultiByte(CP_ACP, 0, FindFileData.cFileName, -1, file_na, iLength,
                        NULL, NULL);
                    strcat_s(test_path_c, file_na);
                    CString cstr_c = test_path_c;
                    LPCTSTR path_c = (LPCTSTR)cstr_c;
                    //簡單判斷下是否另一個盤是否有這個文件
                    //該判斷只寫了個單向的,真正判斷兩個盤枚舉文件的正確性需要再寫一個判斷                    
                    HANDLE fFile = (HANDLE)CreateFile(path_c, GENERIC_WRITE | GENERIC_READ,
                        FILE_SHARE_READ, NULL, OPEN_EXISTING,
                        FILE_ATTRIBUTE_NORMAL, NULL);
                    DWORD lss0 = GetLastError();
                    CloseHandle(fFile);
                    if (lss0 == 2) {
                        wcout << "--------------------------------------------------------"
                            << "---------------------------The another disk is no this file "
                            << "!!!!!!!!!!!!!!!!!!!!!!!!!!" << endl;
                    }
                }
            }
        }
        FindClose(hFind);
        return 0;
    }
}

TEST_P(EnumFileTest, HandleTrueReturn1) {
    char test_path_c[100];
    strcpy_s(test_path_c, test_c_7);
    strcat_s(test_path_c, "EnumFileTest");
    size_t len_c = strlen(test_path_c) + 1;
    size_t converted_c = 0;
    wchar_t *path_c = (wchar_t*)malloc(len_c * sizeof(wchar_t));
    mbstowcs_s(&converted_c, path_c, len_c, test_path_c, _TRUNCATE);
    DWORD lss1 = TraverseDirectory(path_c, 'C');
    char test_path[100];
    strcpy_s(test_path, test_7);
    strcat_s(test_path, "EnumFileTest");
    size_t len = strlen(test_path) + 1;
    size_t converted = 0;
    wchar_t *path = (wchar_t*)malloc(len * sizeof(wchar_t));
    mbstowcs_s(&converted, path, len, test_path, _TRUNCATE);
    DWORD lss2 = TraverseDirectory(path, 'A');
    EXPECT_EQ(lss1, lss2);
}

INSTANTIATE_TEST_CASE_P(Return, EnumFileTest, testing::Values(0));
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章