0

I've a C program that gives prime numbers up to the input number. I want to test this program, and see if it gives composite numbers. Now I need to implement the test, which I find difficult. So I'll appreciate if anybody can help me.

Here is my Checkprime.c:

#include "defs.h"
#include "externs.h"
#include "minunit.h"

int CheckPrime(int K){

int J;

for (J=2; J*J <= K; J++){
  if (Prime[J] == 1){
     if (K % J == 0)  {
        Prime[K] = 0;
        return 0;
     }
   }

}   

Prime[K] = 1; 
return 1;
}

This is my main.c

#include <stdio.h>
#include "defs.h"
#include "checkprime.c"

int Prime[MaxPrimes]; 

int main()
{ 
int UpperBound;
int N;
int *ba = &UpperBound;

printf("enter upper bound\n");
scanf("%d",ba);

Prime[2] = 1;

for (N = 3; N <= *ba; N+= 2){
  CheckPrime(N);
  if (Prime[N]== 1) printf("%d is a prime\n",N);
 }
}

And here is my minunit.c (test, which is implemented):

#undef NDEBUG
#ifndef _minunit_h
#define _minunit_h

#include <stdio.h>
#include <stdlib.h>

#define mu_suite_start() char *message = NULL

#define mu_assert(test, message) if (!(test)) { return message; }
#define mu_run_test(test) \                 
message = test(); tests_run++; if (message) return message;

#define RUN_TESTS(name) int main(int argc, char *argv[]) {\
argc = 1; \
    printf("----\nRUNNING: %s\n", argv[0]);\
    char *result = name();\
    if (result != 0) {\
        printf("FAILED: %s\n", result);\
    }\
    else {\
        printf("ALL TESTS PASSED\n");\
    }\
printf("Tests run: %d\n", tests_run);\
    exit(result != 0);\
}

int tests_run;

#endif

I found the minunit.c on the internet, and I don't know how to implement the test I want, and let it work. My goal is to make a simple test for my program.

Nasc
  • 65
  • 9

2 Answers2

1

And here is my minunit.c …

I presume you meant minunit.h. Given that, you could implement the test like mu_checkprime.c:

#include "checkprime.c"

int Prime[MaxPrimes]; 

static char *test_primes()
{
    mu_assert(CheckPrime(2) == 1,   "2 not found to be prime");
    mu_assert(CheckPrime(3) == 1,   "3 not found to be prime");
    mu_assert(CheckPrime(5) == 1,   "5 not found to be prime");
    mu_assert(CheckPrime(7) == 1,   "7 not found to be prime");
    mu_assert(CheckPrime(11) == 1, "11 not found to be prime");
    mu_assert(CheckPrime(13) == 1, "13 not found to be prime");
    return 0;
}

static char *test_composites()
{
    mu_assert(CheckPrime(1) == 0,   "1 found to be prime");
    mu_assert(CheckPrime(4) == 0,   "4 found to be prime");
    mu_assert(CheckPrime(6) == 0,   "6 found to be prime");
    mu_assert(CheckPrime(8) == 0,   "8 found to be prime");
    mu_assert(CheckPrime(9) == 0,   "9 found to be prime");
    mu_assert(CheckPrime(10) == 0, "10 found to be prime");
    mu_assert(CheckPrime(12) == 0, "12 found to be prime");
    mu_assert(CheckPrime(14) == 0, "14 found to be prime");
    return 0;
}

static char *all_tests()
{
     mu_suite_start();
     mu_run_test(test_primes);
     mu_run_test(test_composites);
     return 0;
}

RUN_TESTS(all_tests)
Armali
  • 18,255
  • 14
  • 57
  • 171
0

Ultimately, a test is nothing more than some code which exercises your code and checks your assumptions are true. When you're starting out, keep it simple. Instead of using a testing framework, start with just assert().

Here is how you can test CheckPrime().

#include <assert.h>
#include "checkprime.h"

void test_CheckPrime_primes() {
    int primes[] = {
        2, 3, 5, 7, 11, 13, 0
    };

    for( int idx = 0; primes[idx] != 0; idx++ ) {
        assert( CheckPrime(primes[idx]) );
    }
}

void test_CheckPrime_composites() {
    int composites[] = {
        1, 4, 6, 8, 9, 10, 12, 14, 0
    };

    for( int idx = 0; composites[idx] != 0; idx++ ) {
        assert( !CheckPrime(composites[idx]) );
    }
}

int main() {
    test_CheckPrime_primes();
    test_CheckPrime_composites();

    return 0;
}

This simple test program will reveal problems with using CheckPrime(). The two biggest are that it does not have a header file and Primes must be initialized by the caller. It will also allow you to learn what sort of assertions to write. For example, what happens with 0? 1? -1? INT_MAX? A candidate larger than your Primes array?

Once you've got the basics down and understand what testing is all about, assert() can be replaced with more informative asserts and a testing framework.

Community
  • 1
  • 1
Schwern
  • 153,029
  • 25
  • 195
  • 336
  • Basicaly: How do you know the testing regime is accurate. Leading to infinite regression. – Arif Burhan Feb 28 '16 at 04:04
  • 1
    Wouldn't it be better to use a framework? It's what I've seen on the Internet – Nasc Feb 28 '16 at 10:04
  • @Nasc Yes. But when learning testing a complicated framework can get in the way and make things testing seem very complicated, especially in C. Yours has some hairy macros. Get the concept of testing working with a normal program, calling a normal library, and using `assert` and `printf`. Then choose a framework. – Schwern Feb 28 '16 at 21:08
  • @ArifBurhan Newbies always worry about that, but it's rare to make a mistake in the code and a mistake in the test such that they line up to equal a passing test. Testing can never prove a code has no bugs, it can only prove it doesn't have the ones you think to test for. It's risk management. Just because you can't lower the risk of bugs to zero doesn't mean you shouldn't significantly lower the risk. However, debating the utility of unit testing is not what this question is about. – Schwern Feb 28 '16 at 21:21