dimanche 1 novembre 2020

Testing navigation - IncompatibleClassChangeError -TestNavHostController is declared final

I'm trying to test navigation in my sample app. I've taken the google navigation testing tutorial. Here's my code:

    @RunWith(AndroidJUnit4::class)
    @LargeTest
    class NavigationTest {
        @get:Rule
        val activityRule = ActivityScenarioRule(MainActivity::class.java)
    
        @Test
        fun checkNavigation() {
            // -------- crash --------
            val navController = 
                TestNavHostController(ApplicationProvider.getApplicationContext())
            // -----------------------

            navController.setGraph(R.navigation.nav_graph)
            val fragmentScenario = launchFragmentInContainer<FirstFragment>()
            fragmentScenario.onFragment { frag ->
                Navigation.setViewNavController(frag.requireView(), navController)
            }
   
            onView(withId(R.id.button_first)).perform(click())
            assertEquals(navController.currentDestination?.id, R.id.SecondFragment)
        }
    }

I'm getting a crash on first line of test:

java.lang.IncompatibleClassChangeError: Superclass androidx.navigation.NavHostController of androidx.navigation.testing.TestNavHostController is declared final (declaration of 'androidx.navigation.testing.TestNavHostController' appears in /data/app/myApp.test-2vutApQLPNgS6e58B0_9tQ==/base.apk)

my test-related build.gradle lines:

    androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
    androidTestImplementation 'androidx.test:runner:1.3.0'
    androidTestImplementation 'androidx.test:rules:1.3.0'
    androidTestImplementation "androidx.navigation:navigation-testing:2.3.1"
    androidTestImplementation "androidx.fragment:fragment-testing:1.2.5"
    testImplementation 'junit:junit:4.13.1'
    androidTestImplementation 'androidx.test.ext:junit:1.1.2'

I've tried this on two phones and it's the same on both (Samsung with Android 8.0 and Huawei with Android 10)

I only saw this crash in relation to firebase, and the answer was to update my sdk-tools. I did, but no luck. I can't find any answers on this topic. Any idea how can I solve this issue?

Dependency injection with C. How run all the tests?

so I'm using [MinUnit][1] to run my tests with C.

This is the library:

 /* file: minunit.h */
 #define mu_assert(message, test) do { if (!(test)) return message; } while (0)
 #define mu_run_test(test) do { char *message = test(); tests_run++; \
                                if (message) return message; } while (0)
 extern int tests_run;

And this is an example of how I use it.

#include "minunit.h"
#include "function_under_test_source.c"
static char *test_ac1() {
    mu_assert("max char, should broke, it didn't",
              function_under_test() == 1);
    return 0;
}
static char *all_tests() {
    mu_run_test(test_ac1);
    return 0;
}
int main(int argc, char **argv) {
    char *result = all_tests();
    if (result != 0) {
        printf("%s\n", result);
    } else {
        printf("ALL TESTS PASSED\n");
    }
    printf("Tests run: %d\n", tests_run);

    return result != 0;
}

There is a little bit of boiler plate to write every time but it fits my purpose.

Now, to be able to abstract the testing from production code, I wanted to use dependency injection. For example if I want to test a function that uses getchar what I do is this:

int get_string(char s[], int maxChar, int (*getchar)()) {

so I pass the pointer to the actual function and then I mock it on the test like:

const char *mock_getchar_data_ptr;

char        mock_getchar() {
    return *mock_getchar_data_ptr++;
}

And then I use it in my test like this:

static char *test_ac2() {
    char text[100];
    mock_getchar_data_ptr = "\nhello!\n"; // the initial \n is there because I'm using scanf on production code (main.c)
    get_string(text, 100, mock_getchar);
    mu_assert("text is hello", strcmp(text, "hello!") == 0);
    return 0;
}

This is working but the problem is that I'm creating a C file for each unit test and then I'm compiling each test file and run the compiled version to test that it's working.

I of course can make a makefile but I was wondering if there is a more automatic orchestration for the tests.

Thanks [1]: http://www.jera.com/techinfo/jtns/jtn002.html

Cannot mock axios service call within a jest test for a React Typescript component

I have a react frontend with a spring boot service that is my backend. Then I have a simple UsersList component:

import React from "react";
import "../../App.css";
import {IUser} from "../../model/interfaces.model";
import axios from "axios"

export class UsersListState {
    constructor(public readonly users: IUser[], public readonly loading: boolean) {
    }
}

export default class UserList extends React.Component<{}, UsersListState> {
    constructor(props) {
        super(props);
        this.state = new UsersListState([], true);
    }

    componentDidMount() {
        axios.get("/api/users")
            .then((res) => {
                console.log(res.data);
                this.setState(new UsersListState(res.data, false));
            })
            .catch((error) => {
                console.log("Could not load users: ", error);
                this.setState(new UsersListState([], false));
            });
    }

    render() {
        if (this.state.loading) {
            return (
                <div data-testid="loading">
                    <h4>Loading...</h4>
                </div>
            );
        } else {
            if (!Array.isArray(this.state.users) || !this.state.users.length) {
                return (
                    <div data-testid="no-users">
                        <h4>No users found matching your request.</h4>
                    </div>
                );
            } else {
                return (
                    <div data-testid="users">
                        {this.state.users.map((user) => (
                            <div key={user.id}>
                                {user.name}, {user.status}
                            </div>
                        ))}
                    </div>
                );
            }
        }
    }
}

My IUser model:

export interface IUser {
    id: string;
    name: string;
    status: string;
}

Here is my simple test UserList.test.ts:

import React from "react";
import "@testing-library/jest-dom/extend-expect";
import {cleanup, render} from "@testing-library/react";
import renderer from "react-test-renderer";
import UserList from "../UserList";

beforeEach(() => {
    jest.resetModules();
    jest.clearAllMocks();
});

afterEach(cleanup);

test("renders list of users from backend", () => {
    const {getByTestId} = render(<UserList/>);
    // this fails, as it renders "loading" testid instead
    expect(getByTestId("users")).toHaveTextContent("John Doe");
});

test("matches snapshot", () => {
    const tree = renderer.create(<UserList/>).toJSON();
    expect(tree).toMatchSnapshot();
});

And last but not least, I have an axios.js manual mock in the mocks directory:

module.exports = {
    get: jest.fn((url) => {
        const users = [
            {
                id: "6bd50444-14e1-4d2d-bca3-221318fad8a7",
                name: "John Doe",
                status: "available",
            }
        ];

        if (url === '/api/users') {
            return Promise.resolve({
                data: users
            });
        }
    }),
    create: jest.fn(function () {
        return this;
    })
};

So my test fails, as it renders "loading" test id. And I guess that's because my axios mock is not recognised? Can you spot what am I doing wrong?

get session value in Mockito

this is my mockito code to call login servlet to get session and share the session between test case

public class MokitoExtension implements BeforeAllCallback, AfterAllCallback {

    protected HttpSession httpSession;

    public HttpSession getHttpSession() {
        return httpSession;
    }

    @Override
    public void beforeAll(ExtensionContext extensionContext) throws Exception {
        Map<String, Object> attributes          = new HashMap<>();
        HttpServletRequest  request             = mock(HttpServletRequest.class);
        HttpServletResponse response            = mock(HttpServletResponse.class);
        ServletOutputStream servletOutputStream = mock(ServletOutputStream.class);
                            httpSession         = mock(HttpSession.class);
         
        JSONObject reqObj = new JSONObject();
        reqObj.put("AccessorCode", "userName");
        reqObj.put("password"    , "password");

        when(request.getReader()).thenReturn(new BufferedReader(new StringReader(reqObj.toString())));
        when(request.getHeader("Content-Type")).thenReturn("application/json");
        when(response.getOutputStream())       .thenReturn(servletOutputStream);
        when(request.getSession())             .thenReturn(httpSession);

        // this line call login servlet and set session.setAttribute("accessor", authenticateAccessor);
        new LogInAPI().doPost(request, response);

    }

Now When I Want to get request.getSession("accessor") but return null

then Try to get Session with this way

 Mockito.doAnswer(new Answer() {
            @Override
            public Object answer(InvocationOnMock aInvocation) throws Throwable {
                String key   = (String) aInvocation.getArguments()[0];
                Object value = aInvocation.getArguments()[1];
                attributes.put(key, value);
                return null;
            }
        }).when(httpSession).setAttribute(anyString(), anyObject())

but this method don't work for put session attribute into hashMap

I see some posts like this click here, partial-mocking-on-httpsession but not solve my issue

Detected dynamic parameter In performance test time out in visual studio 2017

After recording web performance test , the detection of dynamic parameter work without stop and finally time out , I searched for it many without solution , check below image

This Image Explain the situation

Use Pytest fixture with Flask-testing LiveServerTestCase

I am writing automated UI tests for my Flask app using Selenium and LiveServerTestCase from Flask testing.

This is how I have everything set up:

conftest.py

import pytest
from selenium import webdriver


@pytest.yield_fixture(scope="session")
def chrome_browser():
    browser = webdriver.Chrome()
    yield browser
    browser.quit()

test_main_page.py

from app import create_app
from flask_testing import LiveServerTestCase
import multiprocessing


class TestMainPage(LiveServerTestCase):
    multiprocessing.set_start_method("fork")

    def create_app(self):
        app = create_app()
        app.config['TESTING'] = True
        app.config.update(LIVESERVER_PORT=9898)
        return app

    def test_main_page(self, chrome_browser):
        driver = chrome_browser
        assert 1 == 1

Running Pytest giving me the following exception:

FAILED test_main_page.py::TestMainPage::test_main_page - TypeError: test_main_page() missing 1 required positional argument: 'chrome_browser'

When removing the LiveServerTestCase from the TestMainPage class, the fixture chrome_browser is working just fine.

How can I use both LiveServerTestCase and Pytest fixtures?

Thanks

samedi 31 octobre 2020

Accessing a variable in a data frame by columns number in R?

I hope you haven't gotten corona virus and you are all healthy. I have a data frame as "df" and 41 variables var1 to var41. If i write this command

pcdtest(plm(var1~ 1 , data = df, model = "pooling"))[[1]]

i can see the test value. But i need to apply this test for 41 times. I want to access variable by column number which is "df[1]" for "var1" and "df[41]" for "var41"

pcdtest(plm(df[1]~ 1 , data = dfp, model = "pooling"))[[1]]

Bu it fails. Could you please help me to do this? I will have result in for loop. And i will calculate the descriptive statistics for all the results. But it is very difficult to do test for each variable.