fga-eps-mds / 2020.2-Anunbis

Aplicação que auxilia na avaliação de professores e disciplinas da UnB. Anunbis: https://anunbis-frontend.herokuapp.com/. Anunbis-API: http://anunbis-backend.herokuapp.com/
https://fga-eps-mds.github.io/2020.2-Anunbis/
GNU General Public License v3.0
5 stars 11 forks source link

Testes das rotas #157

Closed thiagohdaqw closed 3 years ago

thiagohdaqw commented 3 years ago

Descrição:

Agora que o ambiente já tá configurado, é importante implementar os testes das rotas já feitas. Além disso, deve arrumar os possíveis bugs e aumentar a cobertura de teste ao máximo possível.

Tarefas:

Critérios de aceitação:

thiagohdaqw commented 3 years ago

Como rodar os testes

https://github.com/fga-eps-mds/2020.2-Anunbis/issues/152#issuecomment-816999877

thiagohdaqw commented 3 years ago

Métodos úteis do Unittest

Method

Checks that

assertEqual(a, b)

a == b

assertNotEqual(a, b)

a != b

assertTrue(x)

bool(x) is True

assertFalse(x)

bool(x) is False

assertIs(a, b)

a is b

assertIsNot(a, b)

a is not b

assertIsNone(x)

x is None

assertIsNotNone(x)

x is not None

assertIn(a, b)

a in b

assertNotIn(a, b)

a not in b

assertIsInstance(a, b)

isinstance(a, b)

assertNotIsInstance(a, b)

not isinstance(a, b)

thiagohdaqw commented 3 years ago

Atributos do Response

image

json The return de jsonify from de data.
accept_ranges The Accept-Ranges header.
age The Age response-header field conveys the sender’s estimate of the amount of time since the response (or its revalidation) was generated at the origin server.
allow The Allow entity-header field lists the set of methods supported by the resource identified by the Request-URI.
autocorrect_location_header
automatically_set_content_length
cache_control The Cache-Control general-header field is used to specify directives that MUST be obeyed by all caching mechanisms along the request/response chain.
charset
content_encoding The Content-Encoding entity-header field is used as a modifier to the media-type.
content_language The Content-Language entity-header field describes the natural language(s) of the intended audience for the enclosed entity.
content_length The Content-Length entity-header field indicates the size of the entity-body, in decimal number of OCTETs, sent to the recipient or, in the case of the HEAD method, the size of the entity-body that would have been sent had the request been a GET.
content_location The Content-Location entity-header field MAY be used to supply the resource location for the entity enclosed in the message when that entity is accessible from a location separate from the requested resource’s URI.
content_md5 The Content-MD5 entity-header field, as defined in RFC 1864, is an MD5 digest of the entity-body for the purpose of providing an end-to-end message integrity check (MIC) of the entity-body.
content_range The Content-Range header as ContentRange object.
content_type The Content-Type entity-header field indicates the media type of the entity-body sent to the recipient or, in the case of the HEAD method, the media type that would have been sent had the request been a GET.
data A descriptor that calls get_data() and set_data().
date The Date general-header field represents the date and time at which the message was originated, having the same semantics as orig-date in RFC 822.
default_mimetype
default_status
expires The Expires entity-header field gives the date/time after which the response is considered stale.
implicit_sequence_conversion
is_sequence If the iterator is buffered, this property will be True.
is_streamed If the response is streamed (the response is not an iterable with a length information) this property is True.
last_modified The Last-Modified entity-header field indicates the date and time at which the origin server believes the variant was last modified.
location The Location response-header field is used to redirect the recipient to a location other than the Request-URI for completion of the request or identification of a new resource.
mimetype The mimetype (content type without charset etc.)
mimetype_params The mimetype parameters as dict.
retry_after The Retry-After response-header field can be used with a 503 (Service Unavailable) response to indicate how long the service is expected to be unavailable to the requesting client.
status The HTTP Status code
status_code The HTTP Status code as number
stream The response iterable as write-only stream.
vary The Vary field value indicates the set of request-header fields that fully determines, while the response is fresh, whether a cache is permitted to use the response to reply to a subsequent request without revalidation.
www_authenticate The WWW-Authenticate header in a parsed form.
thiagohdaqw commented 3 years ago

Resultados

Após longo trabalho, acredito que consegui cobrir boa parte do codigo e das possibilidades. Como mostra a figura abaixo, implementei 44 tests que testam as rotas ja criadas até aqui. image

Consegui uma cobertura de 91% image

thiagohdaqw commented 3 years ago

Possivel problema - Encapsulamento entre as camadas e MVC

Não consegui uma cobertura acima de 91% porque boa parte do codigo da pasta app/model/entity/ não está sendo usado. O pacote entity, pelo MVC, é onde deve ficar as classes que representam as entidades. Essas entidades são o meio principal de transporte de dados entre os pacotes (model -> controller -> view). No entanto, o transporte de dados por meio das entidades não está sendo respeitado, pois as classes de DAO, que deveriam transitar apenas no pacote model, estão viajando todas as camadas. Assim, esse é um problema arquitetural que deve ser corrigido.

Exemplo

O metodo get da classe ProfessorList, que está em app/controller/professor_resources.py, é responsavel por retornar todo os professores onde o nome contém tal substring, ou seja, pesquisando professor por parte do nome. image Veja que, na primeira linha do método, ele chama o metodo `app.model.professor_services.get_professor_name_contains(name) que retorna um array com todos professores encontrados.

image Esse metodo que está no pacote model está retornando para o pacote controller diretamente uma entidade do DAO. E isso é um problema. Além disso, esse problema ocorre também no schema de professor: image

Por que isso seria um problema?

O MVC sugere uma boa restrição entre as camadas porque isso diminui o aclopamento e aumenta o encapsulamento, pois um pacote, que nao é o model, nao deve saber especificamente de uma entidade do banco de dados, que é o coração do programa. Por exemplo, para você dirigir um carro, você não precisa necessariamente saber toda a teoria física que acontece nas explosões dentro do motor.

Uma possivel solução

Como implementado no arquivo app/model/services/course_services.py, o metodo get_couse está retornando um array com varias instancias da entidade Curso, e não o CursoDAO, como ocorre no caso do professor. image

app.model.entity.couse.Course image

app.view.course_schema.CourseSchema image

Note que dessa forma as camadas ficam isoladas e a coisa mais importante que é o CourseDAO está sendo transmitido empacotado pela entidade Course.

thiagohdaqw commented 3 years ago

Outro possivel problema - DAO

Pelo padrao DAO, as classes EntidadeDAO deveria ser responsavel por representar a tabela entidade do banco de dados, o seu acesso e seu CRUD. No entanto, no projeto, o pacote model.services que está fazendo o papel de CRUD. Acredito que colocar esses métodos no seu respectivo DAO e deixar o services para logica de negocio e transmissão dos dados diminuiria bastante o acoplamento, uma vez que a casse DAO é responsável por apenas uma coisa (tabela do banco de dados) e deveria saber fazer isso bem.

referencias: https://www.oracle.com/java/technologies/data-access-object.html

RcleydsonR commented 3 years ago

Creio ter entendido os problemas que estão rolando, então está basicamente havendo um mau uso das classes entidadeDAO. Podemos usar também a ideia de DTO desde que não deixe nosso modelo muito poluído e/ou redundante.