From f2085bdb82032a7a9455d52efdf41e8e7cd55058 Mon Sep 17 00:00:00 2001 From: BobSolyman Date: Wed, 14 Jan 2026 16:33:41 +0100 Subject: [PATCH 1/2] [solymasn] Adding tests --- coverage-report.pdf | Bin 0 -> 50326 bytes diffusion2d.py | 9 ++- requirements.txt | 4 ++ tests/integration/test_diffusion2d.py | 70 ++++++++++++++++++++++ tests/unit/test_diffusion2d_functions.py | 71 +++++++++++++++++++++++ tox.ini | 13 +++++ 6 files changed, 166 insertions(+), 1 deletion(-) create mode 100644 coverage-report.pdf create mode 100644 requirements.txt create mode 100644 tox.ini diff --git a/coverage-report.pdf b/coverage-report.pdf new file mode 100644 index 0000000000000000000000000000000000000000..e6d82068e459355619af480a13a711623631572a GIT binary patch literal 50326 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 F{{am}Q)2)C literal 0 HcmV?d00001 diff --git a/diffusion2d.py b/diffusion2d.py index 51a07f2..17bc002 100644 --- a/diffusion2d.py +++ b/diffusion2d.py @@ -38,6 +38,10 @@ def __init__(self): self.dt = None def initialize_domain(self, w=10., h=10., dx=0.1, dy=0.1): + assert isinstance(w, float), "w must be a float" + assert isinstance(h, float), "h must be a float" + assert isinstance(dx, float), "dx must be a float" + assert isinstance(dy, float), "dy must be a float" self.w = w self.h = h self.dx = dx @@ -45,7 +49,10 @@ def initialize_domain(self, w=10., h=10., dx=0.1, dy=0.1): self.nx = int(w / dx) self.ny = int(h / dy) - def initialize_physical_parameters(self, d=4., T_cold=300, T_hot=700): + def initialize_physical_parameters(self, d=4., T_cold=300., T_hot=700.): + assert isinstance(d, float), "d must be a float" + assert isinstance(T_cold, float), "T_cold must be a float" + assert isinstance(T_hot, float), "T_hot must be a float" self.D = d self.T_cold = T_cold self.T_hot = T_hot diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..021aae7 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,4 @@ +numpy +matplotlib +pytest +coverage diff --git a/tests/integration/test_diffusion2d.py b/tests/integration/test_diffusion2d.py index fd026b4..2780559 100644 --- a/tests/integration/test_diffusion2d.py +++ b/tests/integration/test_diffusion2d.py @@ -2,6 +2,7 @@ Tests for functionality checks in class SolveDiffusion2D """ +import numpy as np from diffusion2d import SolveDiffusion2D @@ -10,6 +11,35 @@ def test_initialize_physical_parameters(): Checks function SolveDiffusion2D.initialize_domain """ solver = SolveDiffusion2D() + + # Initialize domain with specific values + w = 12.0 + h = 12.0 + dx = 0.4 + dy = 0.4 + solver.initialize_domain(w, h, dx, dy) + + # Initialize physical parameters + d = 3.0 + T_cold = 250.0 + T_hot = 750.0 + solver.initialize_physical_parameters(d, T_cold, T_hot) + + # Manually calculate expected dt + dx2 = dx * dx + dy2 = dy * dy + expected_dt = dx2 * dy2 / (2 * d * (dx2 + dy2)) + + # Verify the dt calculation + assert abs(solver.dt - expected_dt) < 1e-10, \ + f"Expected dt={expected_dt}, but got {solver.dt}" + + # Also verify that all parameters are set correctly + assert solver.D == d + assert solver.T_cold == T_cold + assert solver.T_hot == T_hot + assert solver.dx == dx + assert solver.dy == dy def test_set_initial_condition(): @@ -17,3 +47,43 @@ def test_set_initial_condition(): Checks function SolveDiffusion2D.get_initial_function """ solver = SolveDiffusion2D() + w = 10.0 + h = 10.0 + dx = 0.5 + dy = 0.5 + solver.initialize_domain(w, h, dx, dy) + + # Initialize physical parameters + d = 4.0 + T_cold = 300.0 + T_hot = 700.0 + solver.initialize_physical_parameters(d, T_cold, T_hot) + + # Get initial condition + u = solver.set_initial_condition() + + # Verify shape matches domain + expected_shape = (solver.nx, solver.ny) + assert u.shape == expected_shape, \ + f"Expected shape {expected_shape}, but got {u.shape}" + + # Manually compute expected initial condition + # Most values should be T_cold + u_expected = T_cold * np.ones((solver.nx, solver.ny)) + + # Circular disc at center with T_hot + r, cx, cy = 2, 5, 5 + r2 = r ** 2 + for i in range(solver.nx): + for j in range(solver.ny): + p2 = (i * dx - cx) ** 2 + (j * dy - cy) ** 2 + if p2 < r2: + u_expected[i, j] = T_hot + + # Check that the computed u matches expected + assert np.allclose(u, u_expected), \ + "Initial condition array does not match expected values" + + # Verify all values are within [T_cold, T_hot] + assert np.all(u >= T_cold), f"Some values are below T_cold={T_cold}" + assert np.all(u <= T_hot), f"Some values are above T_hot={T_hot}" diff --git a/tests/unit/test_diffusion2d_functions.py b/tests/unit/test_diffusion2d_functions.py index c4277ff..5e9cf7d 100644 --- a/tests/unit/test_diffusion2d_functions.py +++ b/tests/unit/test_diffusion2d_functions.py @@ -2,6 +2,7 @@ Tests for functions in class SolveDiffusion2D """ +import numpy as np from diffusion2d import SolveDiffusion2D @@ -10,6 +11,27 @@ def test_initialize_domain(): Check function SolveDiffusion2D.initialize_domain """ solver = SolveDiffusion2D() + + # Use non-default values to test properly + w = 20.0 + h = 30.0 + dx = 0.5 + dy = 0.2 + + # Call the function + solver.initialize_domain(w, h, dx, dy) + + # Manually calculate expected values + expected_nx = int(w / dx) # int(20.0 / 0.5) = 40 + expected_ny = int(h / dy) # int(30.0 / 0.2) = 150 + + # Assert that the values match + assert solver.nx == expected_nx, f"Expected nx={expected_nx}, but got {solver.nx}" + assert solver.ny == expected_ny, f"Expected ny={expected_ny}, but got {solver.ny}" + assert solver.w == w + assert solver.h == h + assert solver.dx == dx + assert solver.dy == dy def test_initialize_physical_parameters(): @@ -17,10 +39,59 @@ def test_initialize_physical_parameters(): Checks function SolveDiffusion2D.initialize_domain """ solver = SolveDiffusion2D() + w = 15.0 + h = 15.0 + dx = 0.3 + dy = 0.3 + solver.initialize_domain(w, h, dx, dy) + + # Test parameters + d = 2.5 + T_cold = 250.0 + T_hot = 750.0 + + # Call the function + solver.initialize_physical_parameters(d, T_cold, T_hot) + + # Manually calculate expected dt + dx2 = dx * dx + dy2 = dy * dy + expected_dt = dx2 * dy2 / (2 * d * (dx2 + dy2)) + + # Assert values + assert solver.D == d + assert solver.T_cold == T_cold + assert solver.T_hot == T_hot + assert abs(solver.dt - expected_dt) < 1e-10, f"Expected dt={expected_dt}, but got {solver.dt}" def test_set_initial_condition(): """ Checks function SolveDiffusion2D.get_initial_function """ + # Create solver and initialize solver = SolveDiffusion2D() + w = 10.0 + h = 10.0 + dx = 0.5 + dy = 0.5 + solver.initialize_domain(w, h, dx, dy) + + T_cold = 300.0 + T_hot = 700.0 + solver.initialize_physical_parameters(d=4.0, T_cold=T_cold, T_hot=T_hot) + + # Call the function + u = solver.set_initial_condition() + + # Check properties of the returned array + assert u.shape == (solver.nx, solver.ny), f"Expected shape {(solver.nx, solver.ny)}, got {u.shape}" + + # Check that most values are T_cold + assert np.all(u >= T_cold), f"Some values are below T_cold={T_cold}" + assert np.all(u <= T_hot), f"Some values are above T_hot={T_hot}" + + # Check that center has hot temperature (circular disc at center) + cx, cy = 5, 5 + r = 2 + assert u[int(cx/dx), int(cy/dy)] == T_hot, "Center should have T_hot" diff --git a/tox.ini b/tox.ini new file mode 100644 index 0000000..fe5ab38 --- /dev/null +++ b/tox.ini @@ -0,0 +1,13 @@ +[tox] +envlist = py39, py310, py311, py312 + +[testenv] +deps = + -r{toxinidir}/requirements.txt +setenv = + PYTHONPATH = {toxinidir} +commands = + pytest {posargs:tests/} + +[pytest] +testpaths = tests From 3d26d2ad8ddda06019d3cca2979a4adbe9417fd5 Mon Sep 17 00:00:00 2001 From: BobSolyman Date: Wed, 14 Jan 2026 16:46:58 +0100 Subject: [PATCH 2/2] update to use mock in unit testing --- coverage-report.pdf | Bin 50326 -> 50606 bytes tests/unit/test_diffusion2d_functions.py | 26 ++++++++++++++++------- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/coverage-report.pdf b/coverage-report.pdf index e6d82068e459355619af480a13a711623631572a..e64c4c05c4716df97248d71b2cd4bbe727ca948f 100644 GIT binary patch delta 15416 zcmY+rQ*6Z`A;VCET(mK?kxEQ{)LXdHq`$oU8;+@IzR-{?jg{>CpHQP+@` zpiZjB;Z8i0SOgHc%<8!=vFdGX8!p3{60!|9*zMvN>OtIdP#e?ywsJTz9s~hHJ@m|Y zON6~LP2oTy%Y4^H$`0CcOCO0C1c-&wlzE%-$ucf(NITXjnCJp&(OB6-8S(^9HOKi> z8POo@^fUk>3$1h7qY-`4JkpwEqq9kkzT53_jBEhILlpq;Z`y3?E36$&%Y$U3u2g&sJ6YCZOhdTFTK@rzD zei%R`GimCKrMxTiP7l#PHEXOX;?=5UK_op>X>K>{3hEbW%nXvi?2KvYCyDp^_i=rt zy0gVUbvcSaoC}PhLT?J^ad}gGQ_9FALb-QmXhLBWHa1B!XZbDgn;eq^yi2rtEaJU% zY*WkUw+L1awKR9pW#>qK?A&%W<kbIrPG7EK@=BxS5l@7O1+j9F57uU2|dyhv1y4q_aY95DZ8cw3}6=2pECtT zY#}#7mH{Kd-bI`nGAI5t88d*oa0K*oc&x?6JG9{w#a|VgC+tgZ72rYIuf~Bby&L6i zYco2mDuT8BqY5P3nk3}ChJxILwfyT_%+v|mdKg>xp=rh}SRS>w`nwIaRF9i5Ms2*i zz(S#uK}AZ#^6(?{PxJiz`~n)G!d4%KJty0cSI;KXOKj!G)VKAn@X}wt*AM{Y)3JA( zjzNx;?DAKd4*H_^im!#(baEY)CY26t$m6LOF9Wh^fgY zQvJd6*|&~U&CYj=9yg}JXCaR+(f|vpk-jd4eIV&SWY)wxH&5)f2 zT?YM`V^3)gBpGvu;l}(V7$bn$1!Of)yIfXB=k5#?gvT>@GX1;As`tj@gWxy{d32!K zJ9Ayj_uFydNv%5l;lgZ9nXpD~N-`4U3+;^;RnERI{PMRq8CCZLEL7h0%pGj#oA%Yjymi7aR;#7b2E4Lc^@E1 zc=*(hpY_8$hN`cQsgE>a#Ad0*zOlObEhT)=*ON8k=FXeoCrKsTvqkViMq0fB zydg}hfC(wFvEgAtH&4Zg?pa6k?hu;V5a-enxcd`UZO3yS@DQ2=l(h*GrW_o=$;JvN zCTG6Y2j`i6tl?v;^A|_xRJSj$!+-Smfratd>hA+xgAe`9$h?Nb;h9afBuZSw zl7u+)!Q}`}g5W#N7O=&&W|D%a)%j+bU=sFuZIlh(kOW%xz_1YZ;Yw@ESvds&`P2Oh}`8BC%;TMd54 zQ?6o=Q#z;}qV`UoYxECtnSrph2jM&F)O>+2u#vd!%7Q6~g}*3w74uLaTXUO5h@poCVLV}g2$sw#h1dKVeb{rQ>Og`x9%g8ePR_o)X4Vwl&@JMS{tn||sK|>?<7zc^aR?s{{n}-oV*Yn4Nh?Eb-I0|O^^yP* z`wwEJ+G3ElIC*B$<)kpkiuxkQspu^3ePxU_C$^#5YtRa#hB6NzLz}MZbbnL#kkuQ~ z56!AXAh__Bqui@`=Flow=hTJU_n?R3)FGfmA$iC_wsFxv6BrV?SV`dZ@|as&$wsF6 z0WN#b+6%^NdDH{S z#|OinKujzZJ%|7ph8qh)>q0ty1ut6owN$Q!9Veb7*@=HX0d<~BqxUUs=iIYgI!5^w zCR?C^^_SHbSTMv8!}=Cl-cEFv{d2fH;+e}@JZm`)jjbVORW>p&65_uWg zUk65s8O(c%^S^^!7=RNpqOUjCDl~IB{efybBOe$VYcn%IKhZQYC>1Cw?BLF0wUjTq zyp>OL3w?n%S76_xc}#A}mF4BRTo~8wwe^VRFJlGNH;I0!bGxJjPc4lx+~u z;LiZ0PTRk^l(61FqabSdvq*II<~em{1~o`cgkO$n=fC_Dj}j}y$*uCIs3sm{b8ue; zN$$UT=C%i6fCe#@W=|H6jP)E7qmf{?3XEQg<#({R+3TYcz8JGT;IpQ}{63Bex_h8H<>8y+_ABWZ2#dt zcUD~Uz#7W+8^$$`Q>)p}w~+JO({`-B6&6x(RbrSS+hS5FcAYr|ck37n6Lr)bPy*;< zyEir-AR#%$w(qdY2nL!O3P#v#!4y3BCsCUbKPwcI4f-sfZ_?7EZK)7)Ih(pI5mc z853CxI!Dc-#M~j#UxSg{cddKpyF=qI^yv#IAz%DU4&R=XhYoo@2c4o+#SO0!{VoI?h+y=k1TdO?kaL+D6prz3X_2D#Y^O7 zuN=uvI*hBSXc@3G=AHJaAGq(C?(?*>HFf$hE=S4QyHLXxfhiWRnR1&x${yAjzbCn4 z?X=9nzN!n=)S7fiPV=3}SiWEIV5uLe_sQsWo|I(+X=O45GY5CTuC>0`rer;tm0(HJf7}w7!jw+ed?mK)SV7O0;`&dYV5V2^`=dt=7QT#~&VSQuOv@nlJf{;d(W zrTvC%JJAcohN~<2vJUI$vK}O(OO71dgvE{a@!{yY>8Bd}PCkyiGZO%tkAaWBt)WI) zh{NIGD6^m>&PdE}*zT6Y4a=`k;IhtY$jK`Q_D{EyJZ`*C4Xf{)DPvpYxd(})T)OkB zipXS|wa-haXRH#|Gdj?rPhs&R?J25Sl#LyAY6Y0(1>p_%EFHN!Mr=hK6$=RJW-~<` znc!i;DyW;1u(fYPv=Ht-7&BZ`Sd-hCH2pKKrl`SOxnP_t0Kt+H-fhcS0^0 zJ~3me+AOqt?`!Z|WE8_A*3ARiLHU2uqV+3l45}sov!d?5#ZCwbpo0TMvl z!V-3}UZK8}@rkT^Z&9vI05Am)PvFVIG%b@(PlNxJ)wls{X78p*W-%7^m3nPZEt$;9 z^BX*697Z-j9$;AE@ki8m>@+dsQYskYo+>HjJ@bJlIh0Q=b3RDmMPEEY{|g(8{j9V-$zn87Oji=5xm53YR01XGEk6eD(ii`xLaI;sWL+SWIwK z3g_hO7c)-KH-^|sJXc>*tY0)Do8^tS-QMN%?9JCmqurGVOrm@v+VejaUMf90^w>K> z0249MklBfui5-ls;fRTeS=m{*fhXuPfG+zXW`wOL4BRD>dIq6okgz~fJ^shQ(k~FH zLS^t4`tjMlJ|-F{n)!i~NZwq}!bX#ytq-S^b)W1RSoL#B2QvBx4%`Hb_85J1*^Pzj zHnsOGD;UzDgQeDL=BJ&RLOZkPz^o};t`48Z2OPqXWLBSO%!4x~=NC7Ar+==9fPHAn z+p1}aRT+4sWBssOUU}js)$SXH>-dY-u|}cMQ%vE?X2y03HXY4DLt>*#->tK5 zVBKGBWk|Zt?k7GGg?0$a5BR~BZYj)A)2rEaG&fPAm^B{{#DF14%rE57R`Kd3+{6?X`i@565Aqd3d`U=xVHF?$Pn(M{?BjoFugt5*HOY;^I z9==?Ty&85DTJle%aUr^y7dgy95o~Hvw-!3we;qM- zpx7zQeg1Y5fUj=I9IX%wklPDlk(P~tsu80`b#NAcG63PxX@+`rGPmbD6Ow6=v(w&z zaM<5V)-FAB4UX`AH*CI7tQIjeudk(+drw2hIM*7?wDAkmK1jUwWnwT~%XzC~X$bQ_ zjL$E~FBU--{U2`;jA>di)NEa|4ITfyQil%KxAysP0Am`bEMHqp{QsD>qU&iME%eC+ zLBYubq3^%!yMAS=9GgpNHU@N?Ht?R#^qP#mwU31*!w5(hCq?kP(&yC-c`W zT3^S5zmWy0gO3zhk6sDXE#s214oNd(Vr5;7 z^|rLzlq}-n>NAyOm^)MUL7jsKOB0@qJ^(_m0ELGPo}9$cOr7-zc;zG&R=T}=Nf|pc z3=A_fH8uK*+r-VTIOnw=Ntu zQH|a|(3%9BQ=Cnl(4l#=EujZO@drXk=5J$CB0Wd8vX=6d@obzD?En5@G-~1!m5A-h z12}b5#$CzenB&S`U&0R^2z}U|jV|iK4)X?*rVT>XO^|eE9iZ~MP*s#?kT@sPwxE$$ zI5<}@psOnNwK)5meLUOIBG2}7F;h^c(2`zn#%Wp9u z_k4-SvNn0LYNXZL;M@gT$Co7`-#Nzb0>Fbdi%g6Uhu1tw+I7So83Pwh?PDzK|B3{Y zqoDT;KbAK9g2N>^nz$8amX<;PO*SXIh9-KJrc_@pUKF7*ArpaLa@ zCW+Ji>K*o@g6x?tb)O&Z6C(9&$*&zhTl9i`PaJah$_SfM~Mxnlx2+M2#V$E%+u`4}H(6ypuV%OAeJ@WWk?TJP18o5;`*f zDa78C*WS9<-EZcNLxI-#D+_2V*KKU3CC|{FdqkNTfG!gd3e@*V2vz#Wt?fr>cVVbe z6P0hoeW1xzw8$i31`uvGA9I6Bl|q~;3_sPLNHO4b5F^VF4DHFDOQw%$8=Nw%0z0^s z!o}f4_I0x-*)8wFhd=tT#yR*VzQK@_<{m6g<465j5~kva8P~7hx#>D|I<2sbm62sO zC~`tllb28&u4n9h5}e{mh?&$9zQ^1>96(^sT74+|Qh>G33g`w6K0tj67klg#_wz-B zw=nG9BHLt_Ia;^I4jP#jy}{ZO`&T{XD3pabH|1KBpnqgWR+OQRAUjoTZbhVfVs^>> zDbu>(Z†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 J5{i;={}(4b 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 diff --git a/tests/unit/test_diffusion2d_functions.py b/tests/unit/test_diffusion2d_functions.py index 5e9cf7d..36c019f 100644 --- a/tests/unit/test_diffusion2d_functions.py +++ b/tests/unit/test_diffusion2d_functions.py @@ -36,14 +36,16 @@ def test_initialize_domain(): def test_initialize_physical_parameters(): """ - Checks function SolveDiffusion2D.initialize_domain + Checks function SolveDiffusion2D.initialize_physical_parameters """ + # Create solver and mock the required member variables (instead of calling initialize_domain) solver = SolveDiffusion2D() - w = 15.0 - h = 15.0 + + # Manually set the required member variables dx = 0.3 dy = 0.3 - solver.initialize_domain(w, h, dx, dy) + solver.dx = dx + solver.dy = dy # Test parameters d = 2.5 @@ -67,19 +69,27 @@ def test_initialize_physical_parameters(): def test_set_initial_condition(): """ - Checks function SolveDiffusion2D.get_initial_function + Checks function SolveDiffusion2D.set_initial_condition """ - # Create solver and initialize + # Create solver and manually set required member variables (mocking initialize_domain and initialize_physical_parameters) solver = SolveDiffusion2D() + + # Mock the required member variables w = 10.0 h = 10.0 dx = 0.5 dy = 0.5 - solver.initialize_domain(w, h, dx, dy) + solver.w = w + solver.h = h + solver.dx = dx + solver.dy = dy + solver.nx = int(w / dx) + solver.ny = int(h / dy) T_cold = 300.0 T_hot = 700.0 - solver.initialize_physical_parameters(d=4.0, T_cold=T_cold, T_hot=T_hot) + solver.T_cold = T_cold + solver.T_hot = T_hot # Call the function u = solver.set_initial_condition()