SA-MP Forums Archive
[Off] Code coverage para pawn? - Printable Version

+- SA-MP Forums Archive (https://sampforum.blast.hk)
+-- Forum: Non-English (https://sampforum.blast.hk/forumdisplay.php?fid=9)
+--- Forum: Languages (https://sampforum.blast.hk/forumdisplay.php?fid=33)
+---- Forum: Português/Portuguese (https://sampforum.blast.hk/forumdisplay.php?fid=34)
+---- Thread: [Off] Code coverage para pawn? (/showthread.php?tid=632985)



Code coverage para pawn? - Dayvison_ - 23.04.2017

Sу estava pensando mesmo aqui, o quгo ъtil seria uma avaliaзгo do seu script pawn com "code coverage", para criar esta ferramenta eu me basearia nos mйtodos, formas de uso, configuraзхes etc... de Coverage.py

Os passos para atingir este resultado seria o mesmo, porйm em pawn atualmente nгo existem mйtodos para fazer um trace do cуdigo pawn linha por linha, entгo isto й o que precisa ser feito, porйm neste passo eu me perdi totalmente nгo consegui imaginar um mйtodo para qual, alguйm tem uma ideia uma luz?

@Edit tive uma ideia que parece funcional, porйm nгo viбvel com um servidor em produзгo
Programa para compilar o cуdigo Para quem nгo sabe do que se trata, devmedia explica

A ferramenta basicamente faria isto:



Re: Code coverage para pawn? - PT - 23.04.2017

Muitos ja tem tentado e alguns conseguem trazer o Python para o pawn.

Gostei do que voce apresentou agora o povo mais novo que nao entende tanto da matйria muito menos de Python perguntam, para que isto serve?


Anyway й bom ver que voce ainda ca continua eu ando meio ausente, obrigado por compartilhar isso.


Re: Code coverage para pawn? - Adiiti - 23.04.2017

Muito interessante. Realmente o pawn esconde muitas coisas.


Re: Code coverage para pawn? - Bruno13 - 23.04.2017

Seria muito ъtil criar um teste unitбrio em Pawn, tambйm seria de grande utilidade para encontrar bugs ou aplicar correзхes de desempenho e etc.

Jб pensastes em criar uma aplicaзгo externa pra gerar um code coverage para Pawn?


Re: Code coverage para pawn? - Kamper - 23.04.2017

TDD para Pawn, se tratando de desenvolvimento SA-MP nгo valeria a pena. Como o desenvolvimento SA-MP й todo baseado em callbacks e a grande maioria das funcionalidades sгo ligadas a aзхes na tela do usuбrio o TDD ficaria quase que 100% sу de mocks, o que nгo testaria nada.

E sobre o code coverage tambйm acho totalmente desnecessбrio. No caso do exemplo do if, o compilador iria lanзar uma exception informando que existe uma parte do cуdigo que nunca serб executada (Pawn error (225) Unreachable Code error ) nгo sendo necessбrio um coverage.

Й bacana ver que a galera estб entrando mais nessa parte teуrica de programaзгo porйm muita coisa nгo й necessбria ou nгo se aplica quando se trбs para o Pawn (SA-MP)


Re: Code coverage para pawn? - Dayvison_ - 24.04.2017

@PT Jб havia um pequeno trecho do tуpico dando um exemplo, porйm agora eu referкnciei uma matйria do DevMedia

@Adiiti isto й basicamente uma gambiarra, jб que o pawn nгo oferece suporte a um trace completo como este.

@Bruno13 para rodar o teste, haverб trкs items sendo eles: @Kamper um projeto recente meu estб todo baseado em TDD, fazendo simulaзхes, se bem feito pode vir a funcionar ^.^
Ele trata as simulaзхes indiretamente, algo como:
PHP код:
AddFakePlayer(playeridname[], ...) 
Apуs isto todas funзхes nativas como: getplayername, isplayerconnected, getplayerip, getplayerpos, retornam dados desse player fake.

Callbacks para ele eu aciono-as com AddPlayerEvent

Outros testes que nгo necessitam disto, eu uso um fork meu do y_test do ******

Talvez em algumas semanas, eu publique isto, para ajudar a board..

Sobre o erro 225 ele ocorre apenas csao isto aconteзa:
PHP код:
func()
{
    return 
1;
    new 
a;
    return 
a;




Re: Code coverage para pawn? - Kamper - 25.04.2017

Quote:
Originally Posted by Dayvison_
Посмотреть сообщение
@PT Jб havia um pequeno trecho do tуpico dando um exemplo, porйm agora eu referкnciei uma matйria do DevMedia

@Adiiti isto й basicamente uma gambiarra, jб que o pawn nгo oferece suporte a um trace completo como este.

@Bruno13 para rodar o teste, haverб trкs items sendo eles:
  • Obrigatуrio
    • prй-compilador
      Serб escrito em go, pois usarб Template based pre-compile, para detectar coisas como: defined, endinput.
      O prй-compilador irб fazer o seguinte:
      • inserir em cada linha vбlida uma funзгo para passar ao plugin que estб linha foi executada, ou talvez apenas antes e apуs condicionais, para melhorar o desempenho
      • Inicializar o plugin(hook ongamemodeinit), com alguns dados como: numero max de linhas, linhas executadas na parte de compilaзгo(globais)
    • plugin
      Para melhorar o desempenho eu opto por um plugin para gerar o coverage, ele farб a funзгo de gerar um arquivo em um formato para ser lido pelo coverage.py, e uma funзaх para obter o report, durante o run time(calculo)
  • Opcional
    • coverage.py, lк o arquivo gerado pelo plugin e...
@Kamper um projeto recente meu estб todo baseado em TDD, fazendo simulaзхes, se bem feito pode vir a funcionar ^.^
Ele trata as simulaзхes indiretamente, algo como:
PHP код:
AddFakePlayer(playeridname[], ...) 
Apуs isto todas funзхes nativas como: getplayername, isplayerconnected, getplayerip, getplayerpos, retornam dados desse player fake.

Callbacks para ele eu aciono-as com AddPlayerEvent

Outros testes que nгo necessitam disto, eu uso um fork meu do y_test do ******

Talvez em algumas semanas, eu publique isto, para ajudar a board..

Sobre o erro 225 ele ocorre apenas csao isto aconteзa:
PHP код:
func()
{
    return 
1;
    new 
a;
    return 
a;

Tem um trecho de cуdigo para poder me mostrar?


Re: Code coverage para pawn? - Dayvison_ - 25.04.2017

Quote:
Originally Posted by Kamper
Посмотреть сообщение
Tem um trecho de cуdigo para poder me mostrar?
Aqui neste trecho vocк pode ver a parte baseada em simulaзхes(OnPlayerEvent, clickTextDraw, inputDialog), e tambйm os testes comuns ASSERT

Atualmente tenho feito apenas estes eventos, e algumas hooks bбsicas, eu pretendo ir incrementando conforme for necessбrio.

PHP код:
#include <tests>
#include <hooks>
/*
    Passos
1. Adcionar o player(nгo registrado)
2. Testar outros botхes de textdraws
3. Registrar o player
4. Checar no banco de dados se os dados foram inseridos
5. Setar valores nas variaveis dele
6. Remover o player
7. Checar no DB se os dados sгo iguais aos setados
8. Conectar o player(registrado), no id do player acima
9. Checar se variaveis foram limpas
10. Logar o player
11. Mudar valor das variaveis
12. Desconectar o player
13. Checar no DB se os valores foram atualizados
*/
static uvar(string:      test_String[MAX_PLAYERS][15])        = "string",     "\0";
static 
uvar(Float:       test_Float[MAX_PLAYERS])             = "float",       0.0;
static 
uvar(Float:       test_ArrayFloat[MAX_PLAYERS][15])    = "array-float"0.0;
static 
uvar(bool:        test_Bool[MAX_PLAYERS])              = "bool",        false;
static 
uvar(bool:        test_ArrayBool[MAX_PLAYERS][15])     = "array-bool",  false;
static 
uvar(             test_Int[MAX_PLAYERS])               = "int",          0;
static 
uvar(             test_ArrayInt[MAX_PLAYERS][15])      = "array-int",   0;
static 
uvar(BitArray:    test_BitArray<MAX_PLAYERS>)          = "bitarray",    false;
Test:Init()
{
        const 
playerid 0;
    
// 1. Adcionamos um player(nгo registrado)
    
AddFakePlayer(playerid"Unknown_User""127.0.0.1", {130230});
}
hook OnPlayerEvent(playeridplayerEvents:eventid)
{
    static 
step;
    if(
eventid == SELECT_TEXTDRAW)
    {
        
// 2. Testar outro botгo
        
if(!step)
        {
            ++
step;
            
clickTextDraw(playeridloginSignIn[2]);
        }
        else
        {
            
// 3. Registrar o player
            
step 0;
            
clickTextDraw(playeridloginSignUp[2]);
        }
        return;
    }
    
// Certificar de que quando clica no botгo logar, sem estar conectado nada aconteзa
    
ASSERT(!step);
    if(
eventid == DIALOG_INPUT)
    {
        
// 3. Registrar o player
        
inputDialog(playerid"12345");
    }
}
hook OnPlayerLogin(playeridloginType:type)
{
    
// 3. Registrar o player
    
if(type == login_byRegister)
    {
        
// Seleciona os dados da tabela
        
format(gs_QueryBuffersizeof(gs_QueryBuffer), "SELECT * from `"#USERS_TABLE"` where `id`='%d';", getPlayerIDG(playerid));
        
new Cache:cache mysql_query(cHandlegs_QueryBuffer);
        
// Obtem o numero de linhas existentes
        
new rows;
        
cache_get_row_count(rows);
        
        
// Certificar que a linha existe
        
ASSERT(rows == 1);
        
// 4. Checa no banco de dados se os dados foram inseridos
        
new 
            
value_Arrays[15*15], // Salvo em strings, depois convertidos para indices
            
value_String[15],
            
Float:value_Float,
            
Float:value_ArrayFloat[15],
            
value_Bool,
            
bool:value_ArrayBool[15],
            
value_Int,
            
value_ArrayInt[15],
            
value_BitArray
        
;
        
cache_get_value_name(0,       "string",      value_String);
        
ASSERT(strcmp(value_Stringtest_String[playerid]));
        
cache_get_value_name_float(0"float",       value_Float);
        
ASSERT(value_Float == test_Float[playerid]);
        
cache_get_value_name(0,       "array-float"value_Arrays);
        
sscanf(value_Arrays"p<,>a<f>[15]"value_ArrayFloat)
        
ASSERT(arraycmp(value_ArrayFloattest_ArrayFloat[plyerid]));
        
cache_get_value_name_int(0,   "bool",        value_Bool);
        
ASSERT(value_Bool == test_Bool[playerid]);
        
cache_get_value_name(0,       "array-bool",  value_Arrays);
        
sscanf(value_Arrays"p<,>a<d>[15]"_:value_ArrayBool)
        
ASSERT(arraycmp(value_ArrayBooltest_ArrayBool[plyerid]));
        
cache_get_value_name_int(0,   "int",         value_Int);
        
ASSERT(value_Int == test_Int[playerid]);
        
cache_get_value_name(0,       "array-int",   value_Arrays);
        
sscanf(value_Arrays"p<,>a<d>[15]"value_ArrayInt)
        
ASSERT(arraycmp(value_ArrayInttest_ArrayInt[plyerid]));
        
cache_get_value_name_int(0,   "bitarray",    value_BitArray);
        
ASSERT(value_BitArray == _:Bit_Get(test_BitArrayplayerid));
    }