2021-01-19(Gtest 여덟 번째 예 포함)

다섯째 날
아침
오늘 이 여덟 번째 예는 원리적으로 매우 간단하지만 그가 쓴 코드는 정말 무섭다. 뒤에 있는 이 코드들은 갈수록 무섭다고 말할 수 있지만 솔직히 나는 소프트웨어를 만드는 것도 아니고 80%도 쓸 수 없다.
Gtest 팁-9:'연합'매개 변수화 이전 두 절은 프로그램을 편리하게 하기 위해 매개 변수화할 때 각각 클래스, 바늘 변수를 매개 변수로 하여 서로 다른 방법으로 중복된 코드를 피했다. 는'연합'이라는 뜻으로 같은 테스트 수요를 가진 도구류를 합친 다음에 파라미터화 테스트를 할 때'파라미터 설정'(구체적으로 그런 방법으로 얼마나 측정하고 어떻게 측정하는가)을 전달하는 것을 말한다.그러나 이'전송 매개 변수'는 일반적으로 여러 종류가 있기 때문에 Combine()을 사용해야 한다. 구체적인 용법은 예시 코드를 참조한다.(하지만 일단 사용하면 도구류의 인터페이스를 모두 고쳐야 하기 때문에 우리의 테스트 수요에 비해 훨씬 쓸모가 없을 것 같다)
-----------------------------------------------------------------------------------------------------------
// This sample shows how to test code relying on some global flag variables.
// Combine() helps with generating all possible combinations of such flags,
// and each test is given one combination as a parameter.

// Use class definitions to test from this header.
#include "prime_tables.h"

#include "gtest/gtest.h"
namespace {
     

// Suppose we want to introduce a new, improved implementation of PrimeTable
// which combines speed of PrecalcPrimeTable and versatility of
// OnTheFlyPrimeTable (see prime_tables.h). Inside it instantiates both
// PrecalcPrimeTable and OnTheFlyPrimeTable and uses the one that is more
// appropriate under the circumstances. But in low memory conditions, it can be
// told to instantiate without PrecalcPrimeTable instance at all and use only
// OnTheFlyPrimeTable.
class HybridPrimeTable : public PrimeTable {
     
 public:
  HybridPrimeTable(bool force_on_the_fly, int max_precalculated)
      : on_the_fly_impl_(new OnTheFlyPrimeTable),
        precalc_impl_(force_on_the_fly
                          ? nullptr
                          : new PreCalculatedPrimeTable(max_precalculated)),
        max_precalculated_(max_precalculated) {
     }
  ~HybridPrimeTable() override {
     
    delete on_the_fly_impl_;
    delete precalc_impl_;
  }

  bool IsPrime(int n) const override {
     
    if (precalc_impl_ != nullptr && n < max_precalculated_)
      return precalc_impl_->IsPrime(n);
    else
      return on_the_fly_impl_->IsPrime(n);
  }

  int GetNextPrime(int p) const override {
     
    int next_prime = -1;
    if (precalc_impl_ != nullptr && p < max_precalculated_)
      next_prime = precalc_impl_->GetNextPrime(p);

    return next_prime != -1 ? next_prime : on_the_fly_impl_->GetNextPrime(p);
  }

 private:
  OnTheFlyPrimeTable* on_the_fly_impl_;
  PreCalculatedPrimeTable* precalc_impl_;
  int max_precalculated_;
};

using ::testing::TestWithParam;
using ::testing::Bool;
using ::testing::Values;
using ::testing::Combine;

// To test all code paths for HybridPrimeTable we must test it with numbers
// both within and outside PreCalculatedPrimeTable's capacity and also with
// PreCalculatedPrimeTable disabled. We do this by defining fixture which will
// accept different combinations of parameters for instantiating a
// HybridPrimeTable instance.
class PrimeTableTest : public TestWithParam< ::std::tuple<bool, int> > {
     
 protected:
  void SetUp() override {
     
    bool force_on_the_fly;
    int max_precalculated;
    std::tie(force_on_the_fly, max_precalculated) = GetParam();
    table_ = new HybridPrimeTable(force_on_the_fly, max_precalculated);
  }
  void TearDown() override {
     
    delete table_;
    table_ = nullptr;
  }
  HybridPrimeTable* table_;
};

TEST_P(PrimeTableTest, ReturnsFalseForNonPrimes) {
     
  // Inside the test body, you can refer to the test parameter by GetParam().
  // In this case, the test parameter is a PrimeTable interface pointer which
  // we can use directly.
  // Please note that you can also save it in the fixture's SetUp() method
  // or constructor and use saved copy in the tests.

  EXPECT_FALSE(table_->IsPrime(-5));
  EXPECT_FALSE(table_->IsPrime(0));
  EXPECT_FALSE(table_->IsPrime(1));
  EXPECT_FALSE(table_->IsPrime(4));
  EXPECT_FALSE(table_->IsPrime(6));
  EXPECT_FALSE(table_->IsPrime(100));
}

TEST_P(PrimeTableTest, ReturnsTrueForPrimes) {
     
  EXPECT_TRUE(table_->IsPrime(2));
  EXPECT_TRUE(table_->IsPrime(3));
  EXPECT_TRUE(table_->IsPrime(5));
  EXPECT_TRUE(table_->IsPrime(7));
  EXPECT_TRUE(table_->IsPrime(11));
  EXPECT_TRUE(table_->IsPrime(131));
}

TEST_P(PrimeTableTest, CanGetNextPrime) {
     
  EXPECT_EQ(2, table_->GetNextPrime(0));
  EXPECT_EQ(3, table_->GetNextPrime(2));
  EXPECT_EQ(5, table_->GetNextPrime(3));
  EXPECT_EQ(7, table_->GetNextPrime(5));
  EXPECT_EQ(11, table_->GetNextPrime(7));
  EXPECT_EQ(131, table_->GetNextPrime(128));
}

// In order to run value-parameterized tests, you need to instantiate them,
// or bind them to a list of values which will be used as test parameters.
// You can instantiate them in a different translation module, or even
// instantiate them several times.
//
// Here, we instantiate our tests with a list of parameters. We must combine
// all variations of the boolean flag suppressing PrecalcPrimeTable and some
// meaningful values for tests. We choose a small value (1), and a value that
// will put some of the tested numbers beyond the capability of the
// PrecalcPrimeTable instance and some inside it (10). Combine will produce all
// possible combinations.
INSTANTIATE_TEST_SUITE_P(MeaningfulTestParameters, PrimeTableTest,
                         Combine(Bool(), Values(1, 10)));

}  // namespace


그리고 글쓰기 연습하러 가자.전체적인 뜻은 기억할 수 있고 디테일은 잊어버린 것이 있다.
오후.
   선생님의 말씀에 따라 코드를 쓰는 사고방식을 바꾸었다. 테스트부터 디자인하고'시스템'의 전체적인 사상으로 생각해 보니 확실히 큰 성과를 거두었다.   전체적인 사고방식이 달라졌다. 특히 인터페이스와 적용성을 최종 목적으로 할 때'기능 실현'을 위한 것이 아니다.원래는 정말 어리석었다. 생각한 대로 썼고 계획이 전혀 없었다. 재구성도 코드를 더 불필요하게 만들었을 뿐이고 그때 고칠 때 기분이 좋았다는 것이 믿기지 않았다.   마지막 계획은 지난달 흑하 디버깅을 할 때 다른api를 사용했을 때의 느낌에 따라 코드 디자인을 하는 것이다. 가장 뚜렷한 특징은
  • 클라이언트 및 서버측 구분 없음
  • 유형이 아닌 기능에 따라 라이브러리 파일을 분류합니다.
  • 코드, 함수는 간략하게 해야 한다. 우리가 지금 제공하는 프레임워크는api이고 프로그램을 작성하라고 하는 것이 아니라는 것을 기억해라.
  • 물론, 마지막으로 샘플과test,readme 같은 파일을 몇 개 쓸 거예요
  •  이렇게 보면 내가 혼돈하고 복잡했던 일을 명확하게 알 수 있다. 이때부터 말하자면 오래 걸리지 않아 다 할 수 있을 것 같다. 그리고 자신의 API로 프로그램 설계를 체험해 보자. 이렇게 하면 코드를 쓰는 데 전심전력으로 사고 실현 방향을 생각할 수 있다. 조금 있으면 밑바닥을 조정해야 하는 것이 아니라 이전의 코드가 너무 스펙틱했기 때문이다.그리고 사용한 부족함에 따라 수정을 하고 마지막으로 선생님과 학생들에게 체험을 합니다!

    좋은 웹페이지 즐겨찾기