I have to add a code outputing useless things to make it run, why?!

I have an Arduino program. I use ArduinoUnit program for unit testing. I find it don’t pass the unit test. Then I add a simple line (Serial.println(“er”);Serial.flush();//HERE!!!) as you see below. To my surprise, the unit test passed! I tried several times, but the results are the same. I have to add this line to make it work well! Please help me! Thx!

Here is the core code: (The simple strange line is in this code)

class test_WebHelperExtendFake;
class test_WebHelperExtendFake: public test_WebHelperSeriesFake {
public:
    test_WebHelperExtendFake(const char *name): test_WebHelperSeriesFake(name) {}
private:
    class TestWebHelperExtend: public WebHelperExtend {
    public:
        TestWebHelperExtend(byte *mac,
                unsigned long requestDelayTime, test_WebHelperExtendFake *testClassPtr):
                WebHelperExtend(mac,requestDelayTime),testClassPtr(testClassPtr){}

        void receive(bool isFirstChar, uchar ch){
            assertEqual(isFirstChar,testClassPtr->assertIsFirstChar);
            assertTrue(testClassPtr->assertShouldReceive);
            assertTrue(((uchar)testClassPtr->assertReceiveCh)==ch);
            testClassPtr->isRealReceive = true;
        }
    private:
        test_WebHelperExtendFake *testClassPtr;
    };
protected:
    void assertIsRealReceiveAndReset(){
        assertEqual(isRealReceive,assertShouldReceive);
        isRealReceive = false;
    }
    void onInit(){
        helper = new TestWebHelperExtend(MAC,DELAY_TIME,this);
        helper->setup();
    }
    void onConnect(){}
    void onNoAvailableChar(){
        for(int i = 0;i<2;++i){
            assertReceiveCh = 0;
            assertShouldReceive = false;
            helper->loop();
            assertIsRealReceiveAndReset();
        }
    }
    void onHaveAvailableChar(int charNum){
        for(int i = 0;i<charNum;++i){
            if(testDataGetLen<DATA_CONTENT_BEG){
                assertReceiveCh = 0;
                assertShouldReceive = false;
                assertIsFirstChar = false;
            }else{
                assertIsFirstChar = (testDataGetLen==DATA_CONTENT_BEG);
                assertReceiveCh = (uchar)test_WebHelperSeriesFake::TEST_DATA[testDataGetLen];
                assertShouldReceive = true;
            }
            Serial.println("er");Serial.flush();//HERE!!!
            helper->loop();
            assertIsRealReceiveAndReset();
            ++testDataGetLen;
        }
        //After the code above, there is no char available
        onNoAvailableChar();
    }
    void onStop(){
        helper->client.stop();
        helper->loop();
        delay(DELAY_TIME);
    }
    void onDestroy(){
        delete helper;
    }
    FakeEthernetClient *getFakeEthernetClient(){
        return & (helper->client);
    }
private:
    WebHelperExtend *helper;
    static const int DELAY_TIME = 1000;
public:
    uchar assertReceiveCh;//What should be received in the following receive()
    bool assertShouldReceive;//Should we get a receive() call or not
    bool isRealReceive;//If the receiver receive it
    bool assertIsFirstChar;
};
test_WebHelperExtendFake test_WebHelperExtendFake_instance("WebHelperExtendFake");

And this is its base class:

class test_WebHelperSeriesFake: public TestOnce {
public:
    test_WebHelperSeriesFake(const char *name): TestOnce(name) {}
    void once(){
        onInit();
        for(int connI=0;connI<3;++connI){
            testDataPutLen = 0, testDataGetLen = 0;
            onConnect();
            for(int x = 0;x < 5;++x){
                onNoAvailableChar();
                //Have many chars available to read
                const int PUT_CHAR_NUM = 4;
                for(int i = 0;i<PUT_CHAR_NUM;++i){
                    getFakeEthernetClient()->putCharFakeFromWeb(TEST_DATA[testDataPutLen++]);
                }
                onHaveAvailableChar(PUT_CHAR_NUM);
            }
            //Disconnected
            onStop();
        }
        onDestroy();
    }
protected:
    virtual void onInit()=0;
    virtual void onConnect()=0;
    virtual void onNoAvailableChar()=0;
    virtual void onHaveAvailableChar(int charNum)=0;
    virtual void onStop()=0;
    virtual void onDestroy()=0;
    virtual FakeEthernetClient *getFakeEthernetClient()=0;
    static const char TEST_DATA[];
    static const char TEST_DATA_ACTION_CH;
    static const int DATA_CONTENT_BEG = 7;
    int testDataGetLen, testDataPutLen;
};

Here is the class the unit test points to: (Well, its base class WebHelper does passed the unit test. However, if you want the code just comment me, and I will add it immediately.

class test_WebHelperExtendFake;
class WebHelperExtend: public WebHelper{
public:
    enum STATUS{
        READING,
        WAITING,
    };
    class Receiver{
    public:
        virtual void receive(uchar ch)=0;
    };
public:
    WebHelperExtend(byte *mac, unsigned long requestDelayTime = 10000):
        WebHelper(mac),lastReadFinishTime(0),currentStatus(WAITING),
        REQUEST_DELAY_TIME(requestDelayTime){}

    void setup(){
        WebHelper::setup();
    }

    void loop(){
        switch(currentStatus){
        case WAITING:
            if((millis()-lastReadFinishTime)>REQUEST_DELAY_TIME){
                connect(SERVER,PORT,URL);
                currentStatus = READING;
                isFirstChar = true;
            }
            break;
        case READING:
            uchar ch;
            switch(tryRead(ch)){
            case WebHelper::READ_SUCCESS:
                receive(isFirstChar,ch);
                isFirstChar = false;
                break;
            case WebHelper::DISCONNECTED:
                lastReadFinishTime = millis();
                currentStatus = WAITING;
                break;
            case WebHelper::CONNECTION_ALREADY_FINISHED:
                break;
            case WebHelper::NO_NEW:
                break;
            }
            break;
        }
    }
protected:
    virtual void receive(bool isFirstChar, uchar ch)=0;
private:
    STATUS currentStatus;
    unsigned long lastReadFinishTime;
    const unsigned long REQUEST_DELAY_TIME;
    bool isFirstChar;
private:
    friend class test_WebHelperExtendFake;
};

turtlegood: Then I add a simple line (Serial.println("er");Serial.flush();//HERE!!!) as you see below.

It looks like very complex code to start with.

...R

Then I add a simple line (Serial.println("er");Serial.flush();//HERE!!!) as you see below.

Most people would call that two lines.

Serial.println("er");
Serial.flush();

So does the println help, or the flush?

To my surprise, the unit test passed!

What unit test?

Maybe this web site will clear things up:

http://snippets-r-us.com/

Why did you even put that "line" there?

Random experimentation?

[quote author=Nick Gammon date=1430640182 link=msg=2215220] What unit test? [/quote] https://github.com/mmurdoch/arduinounit/ Thx for helping! In fact, only use println or only use flush do not make it run well.

So basically it is a timing issue? I would look there first.

Adding a print statement is like adding a delay. So what ever this program is doing it needs a small delay at that point.

Is the problem in your code or in the test code?

…R