T
T
tj572019-02-05 15:57:11
Software testing
tj57, 2019-02-05 15:57:11

How to properly write tests for a program using libtap/ google test/ VS Test framework?

There is a problem with the following condition: acm.timus.ru/problem.aspx?space=1&num=1085. There is a working code that produces the correct result. The task is to write tests for the program so that each function is tested. I would like to know which of the above technologies is best to use for this particular situation and how to write tests in general? There is an example that shows how to write tests to calculate the factorial function using libtap:

#include "stdafx.h"
#include "Factorial.h"
#define MY_DEF_USE_LIBTAP
#ifdef MY_DEF_USE_LIBTAP
#define TAP_COMPILE 
#include "libtap\cpp_tap.h"

int main(int, char *[]) {
  using namespace std;

  plan_tests(7); 
  ok(Factorial(5) , "Factorial of 5 is equal 120");
  ok1(Factorial(2) );
  ok1(Factorial(3) == 6);
  // тесты на граничные значения
  ok(Factorial(0) == 1, "Factorial of 0 is equal 1");
  ok(Factorial(12) == 479001600, "Factorial of 12");
  // тесты на ошибочные значения
  ok(Factorial(-5) == -1, "Factorial of -5 - error_code = -1");
  ok(Factorial(100) == -2, "Factorial of 100 - error_code = -2");
  //
  return exit_status(); // вывод отчета по тестам

  return 0;
}
#else

#endif

Everything is clear here, but in my case, all methods are either void or bool, so there is a misunderstanding of how to test them by analogy with the factorial function.
Program code:
#include "stdafx.h"
#include <iostream>
#include <map>
#include <set>
#include <vector>
#include <algorithm>
#include <iterator>

using namespace std;

typedef set < int > T_indexes;
typedef T_indexes T_stops;
typedef T_stops T_route;
typedef vector < T_route > T_routes;
typedef int T_cost;
typedef map < T_cost, T_stops > T_stops_of_cost;

struct  T_friend
{
  int money_;
  int stop_ind_;
  bool has_season_ticket_;
  T_stops_of_cost stops_of_cost_;
  T_friend()
    :
    money_{},
    stop_ind_{},
    has_season_ticket_{}
  {}

  void printRoute(T_route route)
  {
    for (int const& stop : route)
    {
      cout << stop << ' ';
    }
  }

  void printRoutes(T_routes routes)
  {
    for (T_route const& route : routes)
    {
      printRoute(route);
    }
  }

  void insertRoute(T_route route, T_routes routes)
  {
    copy(route.begin(), route.end(), inserter(routes, routes.end()));
  }

  void fill_stops_of_cost(int ticket_price, T_routes const & routes)
  {
    if (has_season_ticket_)
    {
      fill_stops_of_cost_with_season_ticket(routes);
    }
    else
    {
      fill_stops_of_cost_with_money(ticket_price, routes);
    }
  }

  void  fill_stops_of_cost_with_season_ticket(T_routes const & routes)
  {
    stops_of_cost_[0].insert(stop_ind_);

    T_indexes processed_routes_indexes;
    bool amended{};

    do
    {
      amended = false;

      for (size_t i{}; i < routes.size(); ++i)
      {
        auto const & route_i = routes[i];

        if (processed_routes_indexes.count(i))
        {
          continue;
        }

        if (stops_has_stop_from_rout(stops_of_cost_[0], route_i))
        {
          amended = true;

          stops_of_cost_[0].insert(route_i.begin(), route_i.end());
          processed_routes_indexes.insert(i);
        }
      }
    } while (amended);
  }

  static bool stops_has_stop_from_rout(T_stops const & stops, T_route const & route)
  {
    for (auto stop : stops)
    {
      if (route.count(stop))
      {
        return  true;
      }
    }
    return  false;
  }

  void fill_stops_of_cost_with_money(int ticket_price, T_routes const & routes)
  {
    stops_of_cost_[0].insert(stop_ind_);
    T_indexes   processed_routes_indexes;

    for (int cost_cur{ ticket_price }; cost_cur <= money_; cost_cur += ticket_price)
    {
      bool amended{};
      auto & stops_of_cost_cur = stops_of_cost_[cost_cur];
      auto & stops_of_cost_prev = stops_of_cost_[cost_cur - ticket_price];

      for (size_t i{}; i < routes.size(); ++i)
      {
        auto const & route_i = routes[i];

        if (processed_routes_indexes.count(i))
        {
          continue;
        }

        if (stops_has_stop_from_rout(stops_of_cost_prev, route_i))
        {
          amended = true;
          stops_of_cost_cur.insert(route_i.begin(), route_i.end());
          processed_routes_indexes.insert(i);
        }
      }

      if (!amended)
      {
        break;
      }
    }
  }

  bool successfully_set_stop_cost(int stop_ind, int & stop_cost) const
  {
    for (auto const & cost_and_stops : stops_of_cost_)
    {
      auto cost_cur = cost_and_stops.first;
      auto const & stops_cur = cost_and_stops.second;
      if (stops_cur.count(stop_ind))
      {
        stop_cost = cost_cur;
        return  true;
      }
    }

    return  false;
  }
};

typedef vector < T_friend  > T_friends;

bool successfully_set_stop_total_cost(int stop_ind, T_friends const & friends, int & res_stop_total_cost)
{
  for (auto const & friend_cur : friends)
  {
    int stop_cur_cost{};
    if (!friend_cur.successfully_set_stop_cost(stop_ind, stop_cur_cost))
    {
      return  false;
    }
    res_stop_total_cost += stop_cur_cost;
  }
  return  true;
}
void calc_result(int stop_ind_min, int n_stop_ind_max, T_friends const & friends)
{
  int stop_ind_res{};
  const int STOP_TOTAL_COST_MIN_START{ -1 };
  int stop_total_cost_min{ STOP_TOTAL_COST_MIN_START };

  for (int stop_ind{ stop_ind_min }; stop_ind <= n_stop_ind_max; ++stop_ind)
  {
    int stop_total_cost{};

    if (successfully_set_stop_total_cost(stop_ind, friends, stop_total_cost) && (stop_total_cost_min == STOP_TOTAL_COST_MIN_START || stop_total_cost < stop_total_cost_min))
    {
      stop_ind_res = stop_ind;
      stop_total_cost_min = stop_total_cost;
    }
  }
  cout << stop_ind_res;

  if (stop_ind_res)
  {
    cout << ' ' << stop_total_cost_min;
  }
  cout << endl;
}

int main()
{
  const int TICKET_PRICE = 4;
  const int STOP_IND_MIN = 1;
  int n_stop_ind_max{};
  int m_routes_total{};
  int k_friends_total{};

  cin >> n_stop_ind_max;
  cin >> m_routes_total;

  T_routes routes(m_routes_total);

  for (auto & route : routes)
  {
    int route_size{};
    cin >> route_size;

    for (int i{}; i < route_size; ++i)
    {
      int stop_ind{};
      cin >> stop_ind;
      route.insert(stop_ind);
    }
  }

  cin >> k_friends_total;
  T_friends friends(k_friends_total);

  for (auto & friend_cur : friends)
  {
    cin >> friend_cur.money_;
    cin >> friend_cur.stop_ind_;
    cin >> friend_cur.has_season_ticket_;
  }

  for (auto & friend_cur : friends)
  {
    friend_cur.fill_stops_of_cost(TICKET_PRICE, routes);
  }

  calc_result(STOP_IND_MIN, n_stop_ind_max, friends);
}

Answer the question

In order to leave comments, you need to log in

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question